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

Reply via email to