Theo pointed me in another direction
Proof of concept that appears to work just fine
(very minimal error checking so far)
Of course, if we end up running a command on somethin too large,
thi will fail as usual, but much to my surprise,
make show=_FULL_FETCH_LIST
in sysutils/telegraf worked with this.
(and then I remembered that echo is a built-in, so there's no long exec
involved)
Index: cmd_exec.c
===================================================================
RCS file: /cvs/src/usr.bin/make/cmd_exec.c,v
retrieving revision 1.11
diff -u -p -r1.11 cmd_exec.c
--- cmd_exec.c 16 Jan 2020 16:07:18 -0000 1.11
+++ cmd_exec.c 26 Aug 2023 20:06:45 -0000
@@ -36,6 +36,7 @@
#include "memory.h"
#include "pathnames.h"
#include "job.h"
+#include "engine.h"
char *
Cmd_Exec(const char *cmd, char **err)
@@ -54,7 +55,7 @@ Cmd_Exec(const char *cmd, char **err)
*err = NULL;
/* Set up arguments for the shell. */
- args[0] = "sh";
+ args[0] = _PATH_BSHELL;
args[1] = "-c";
args[2] = (char *)cmd;
args[3] = NULL;
@@ -82,7 +83,9 @@ Cmd_Exec(const char *cmd, char **err)
(void)close(fds[1]);
}
- (void)execv(_PATH_BSHELL, args);
+ (void)execv(args[0], args);
+ if (errno == E2BIG)
+ retry_with_temp_file(false, args);
_exit(1);
/*NOTREACHED*/
Index: engine.c
===================================================================
RCS file: /cvs/src/usr.bin/make/engine.c,v
retrieving revision 1.71
diff -u -p -r1.71 engine.c
--- engine.c 30 May 2023 04:42:21 -0000 1.71
+++ engine.c 26 Aug 2023 20:06:45 -0000
@@ -549,6 +549,30 @@ recheck_command_for_shell(char **av)
return av;
}
+void
+retry_with_temp_file(bool errCheck, char **args)
+{
+ char template[] = "/tmp/shell.XXXXXXXXXX";
+ int fd;
+ char buf[50];
+ int i = 1;
+
+ fd = mkstemp(template);
+ snprintf(buf, sizeof(buf), "/dev/fd/%d", fd);
+
+ if (fd == -1)
+ return;
+ unlink(template);
+ write(fd, args[2], strlen(args[2]));
+ lseek(fd, 0, SEEK_SET);
+ if (errCheck)
+ args[i++] = "-e";
+ args[i++] = buf;
+ args[i++] = NULL;
+ execv(args[0], args);
+}
+
+
static void
run_command(const char *cmd, bool errCheck)
{
@@ -583,6 +607,8 @@ run_command(const char *cmd, bool errChe
todo = av;
}
execvp(todo[0], todo);
+ if (errno == E2BIG && todo == shargv)
+ retry_with_temp_file(errCheck, todo);
if (errno == ENOENT)
fprintf(stderr, "%s: not found\n", todo[0]);
Index: engine.h
===================================================================
RCS file: /cvs/src/usr.bin/make/engine.h,v
retrieving revision 1.17
diff -u -p -r1.17 engine.h
--- engine.h 13 Jan 2020 15:12:58 -0000 1.17
+++ engine.h 26 Aug 2023 20:06:45 -0000
@@ -138,4 +138,5 @@ extern bool job_run_next(Job *);
*/
extern void handle_job_status(Job *, int);
+extern void retry_with_temp_file(bool, char **);
#endif