Module Name:    src
Committed By:   sjg
Date:           Thu Jul 11 20:09:16 UTC 2024

Modified Files:
        src/usr.bin/make: compat.c main.c make.h
        src/usr.bin/make/unit-tests: var-op-shell.mk

Log Message:
Compat_RunCommand use tempfile if cmd too big

Extract the logic recently added to Cmd_Exec to handle
long commands via temp file to Cmd_Argv,
so it can also be leveraged by Compat_RunCommand

Reviewed by: christos


To generate a diff of this commit:
cvs rdiff -u -r1.259 -r1.260 src/usr.bin/make/compat.c
cvs rdiff -u -r1.631 -r1.632 src/usr.bin/make/main.c
cvs rdiff -u -r1.343 -r1.344 src/usr.bin/make/make.h
cvs rdiff -u -r1.9 -r1.10 src/usr.bin/make/unit-tests/var-op-shell.mk

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/make/compat.c
diff -u src/usr.bin/make/compat.c:1.259 src/usr.bin/make/compat.c:1.260
--- src/usr.bin/make/compat.c:1.259	Sat Jun 15 20:02:45 2024
+++ src/usr.bin/make/compat.c	Thu Jul 11 20:09:16 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: compat.c,v 1.259 2024/06/15 20:02:45 rillig Exp $	*/
+/*	$NetBSD: compat.c,v 1.260 2024/07/11 20:09:16 sjg Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -91,7 +91,7 @@
 #include "pathnames.h"
 
 /*	"@(#)compat.c	8.2 (Berkeley) 3/19/94"	*/
-MAKE_RCSID("$NetBSD: compat.c,v 1.259 2024/06/15 20:02:45 rillig Exp $");
+MAKE_RCSID("$NetBSD: compat.c,v 1.260 2024/07/11 20:09:16 sjg Exp $");
 
 static GNode *curTarg = NULL;
 static pid_t compatChild;
@@ -246,6 +246,8 @@ Compat_RunCommand(const char *cmdp, GNod
 	bool useShell;		/* True if command should be executed using a
 				 * shell */
 	const char *cmd = cmdp;
+	char cmd_file[MAXPATHLEN];
+	size_t cmd_len;
 
 	silent = (gn->type & OP_SILENT) != OP_NONE;
 	errCheck = !(gn->type & OP_IGNORE);
@@ -316,20 +318,20 @@ Compat_RunCommand(const char *cmdp, GNod
 
 	DEBUG1(JOB, "Execute: '%s'\n", cmd);
 
-	if (useShell && shellPath == NULL)
-		Shell_Init();		/* we need shellPath */
+	cmd_len = strlen(cmd);
+	if (cmd_len > MAKE_CMDLEN_LIMIT)
+		useShell = true;
+	else
+		cmd_file[0] = '\0';
 
 	if (useShell) {
 		static const char *shargv[5];
 
-		/* The following work for any of the builtin shell specs. */
-		int shargc = 0;
-		shargv[shargc++] = shellPath;
-		if (errCheck && shellErrFlag != NULL)
-			shargv[shargc++] = shellErrFlag;
-		shargv[shargc++] = DEBUG(SHELL) ? "-xc" : "-c";
-		shargv[shargc++] = cmd;
-		shargv[shargc] = NULL;
+		if (Cmd_Argv(cmd, cmd_len, shargv, 5,
+			cmd_file, sizeof(cmd_file),
+			(errCheck && shellErrFlag != NULL),
+			DEBUG(SHELL)) < 0)
+			Fatal("cannot run \"%s\"", cmd);
 		av = shargv;
 		bp = NULL;
 		mav = NULL;
@@ -422,6 +424,8 @@ Compat_RunCommand(const char *cmdp, GNod
 	}
 
 	free(cmdStart);
+	if (cmd_file[0] != '\0')
+		unlink(cmd_file);
 	compatChild = 0;
 	if (compatSigno != 0) {
 		bmake_signal(compatSigno, SIG_DFL);

Index: src/usr.bin/make/main.c
diff -u src/usr.bin/make/main.c:1.631 src/usr.bin/make/main.c:1.632
--- src/usr.bin/make/main.c:1.631	Tue Jul  9 19:43:01 2024
+++ src/usr.bin/make/main.c	Thu Jul 11 20:09:16 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: main.c,v 1.631 2024/07/09 19:43:01 rillig Exp $	*/
+/*	$NetBSD: main.c,v 1.632 2024/07/11 20:09:16 sjg Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -111,7 +111,7 @@
 #include "trace.h"
 
 /*	"@(#)main.c	8.3 (Berkeley) 3/19/94"	*/
-MAKE_RCSID("$NetBSD: main.c,v 1.631 2024/07/09 19:43:01 rillig Exp $");
+MAKE_RCSID("$NetBSD: main.c,v 1.632 2024/07/11 20:09:16 sjg Exp $");
 #if defined(MAKE_NATIVE)
 __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993 "
 	    "The Regents of the University of California.  "
@@ -1685,6 +1685,56 @@ found:
 	return true;
 }
 
+/* populate av for Cmd_Exec and Compat_RunCommand */
+int
+Cmd_Argv(const char *cmd, size_t cmd_len, const char **av, size_t avsz,
+    char *cmd_file, size_t cmd_filesz, bool eflag, bool xflag)
+{
+	int ac = 0;
+	int cmd_fd = -1;
+
+	if (shellPath == NULL)
+		Shell_Init();
+
+	if (cmd_file != NULL) {
+		if (cmd_len == 0)
+			cmd_len = strlen(cmd);
+
+		if (cmd_len > MAKE_CMDLEN_LIMIT) {
+			cmd_fd = mkTempFile(NULL, cmd_file, cmd_filesz);
+			if (cmd_fd >= 0) {
+				ssize_t n;
+
+				n = write(cmd_fd, cmd, cmd_len);
+				close(cmd_fd);
+				if (n < (ssize_t)cmd_len) {
+					unlink(cmd_file);
+					cmd_fd = -1;
+				}
+			}
+		} else
+			cmd_file[0] = '\0';
+	}
+
+	if (avsz < 4 || (eflag && avsz < 5))
+		return -1;
+
+	/* The following works for any of the builtin shell specs. */
+	av[ac++] = shellPath;
+	if (eflag)
+		av[ac++] = shellErrFlag;
+	if (cmd_fd >= 0) {
+		if (xflag)
+			av[ac++] = "-x";
+		av[ac++] = cmd_file;
+	} else {
+		av[ac++] = xflag ? "-xc" : "-c";
+		av[ac++] = cmd;
+	}
+	av[ac] = NULL;
+	return ac;
+}
+
 /*
  * Execute the command in cmd, and return its output (only stdout, not
  * stderr, possibly empty).  In the output, replace newlines with spaces.
@@ -1703,40 +1753,11 @@ Cmd_Exec(const char *cmd, char **error)
 	char *p;
 	int saved_errno;
 	char cmd_file[MAXPATHLEN];
-	size_t cmd_len;
-	int cmd_fd = -1;
-
-	if (shellPath == NULL)
-		Shell_Init();
 
-	cmd_len = strlen(cmd);
-	if (cmd_len > 1000) {
-		cmd_fd = mkTempFile(NULL, cmd_file, sizeof(cmd_file));
-		if (cmd_fd >= 0) {
-			ssize_t n;
-
-			n = write(cmd_fd, cmd, cmd_len);
-			close(cmd_fd);
-			if (n < (ssize_t)cmd_len) {
-				unlink(cmd_file);
-				cmd_fd = -1;
-			}
-		}
-	}
-
-	args[0] = shellName;
-	if (cmd_fd >= 0) {
-		args[1] = cmd_file;
-		args[2] = NULL;
-	} else {
-		cmd_file[0] = '\0';
-		args[1] = "-c";
-		args[2] = cmd;
-		args[3] = NULL;
-	}
 	DEBUG1(VAR, "Capturing the output of command \"%s\"\n", cmd);
 
-	if (pipe(pipefds) == -1) {
+	if (Cmd_Argv(cmd, 0, args, 4, cmd_file, sizeof(cmd_file), false, false) < 0
+	    || pipe(pipefds) == -1) {
 		*error = str_concat3(
 		    "Couldn't create pipe for \"", cmd, "\"");
 		return bmake_strdup("");

Index: src/usr.bin/make/make.h
diff -u src/usr.bin/make/make.h:1.343 src/usr.bin/make/make.h:1.344
--- src/usr.bin/make/make.h:1.343	Tue Jul  9 19:43:01 2024
+++ src/usr.bin/make/make.h	Thu Jul 11 20:09:16 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: make.h,v 1.343 2024/07/09 19:43:01 rillig Exp $	*/
+/*	$NetBSD: make.h,v 1.344 2024/07/11 20:09:16 sjg Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -845,8 +845,13 @@ void For_Break(struct ForLoop *);
 /* job.c */
 void JobReapChild(pid_t, int, bool);
 
+/* longer than this we use a temp file */
+#ifndef MAKE_CMDLEN_LIMIT
+# define MAKE_CMDLEN_LIMIT 1000
+#endif
 /* main.c */
 void Main_ParseArgLine(const char *);
+int Cmd_Argv(const char *, size_t, const char **, size_t, char *, size_t, bool, bool);
 char *Cmd_Exec(const char *, char **) MAKE_ATTR_USE;
 void Error(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2);
 void Fatal(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2) MAKE_ATTR_DEAD;

Index: src/usr.bin/make/unit-tests/var-op-shell.mk
diff -u src/usr.bin/make/unit-tests/var-op-shell.mk:1.9 src/usr.bin/make/unit-tests/var-op-shell.mk:1.10
--- src/usr.bin/make/unit-tests/var-op-shell.mk:1.9	Sun Jun 30 11:37:21 2024
+++ src/usr.bin/make/unit-tests/var-op-shell.mk	Thu Jul 11 20:09:16 2024
@@ -1,4 +1,4 @@
-# $NetBSD: var-op-shell.mk,v 1.9 2024/06/30 11:37:21 rillig Exp $
+# $NetBSD: var-op-shell.mk,v 1.10 2024/07/11 20:09:16 sjg Exp $
 #
 # Tests for the != variable assignment operator, which runs its right-hand
 # side through the shell.
@@ -99,7 +99,7 @@ OUTPUT_SHORT!=	echo "$$0"
 OUTPUT_LONG!=	echo "$$0" || : ${:U:range=1000}
 # When running '$shell -c $command', '$0' in the shell evaluates to the name
 # of the shell.
-.if ${OUTPUT_SHORT} != ${.SHELL:T}
+.if ${OUTPUT_SHORT:T} != ${.SHELL:T}
 .  error
 .endif
 # When running '$shell $tmpfile', '$0' in the shell evaluates to the name of

Reply via email to