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