I did not point you in this direction, not at all.

I said make execve failure report an accurate error.  Rather than
requiring a special hook which will report the problem.  Meaning
if the problem areas were known, they could be coped with.  What
I'm seeing here appears to be a thing like system(), which will
punt the problem further along, to a shell, which will also probably
report the error poorly -- I suspect the more layers you pile on
top of ARG_MAX and/or E2BIG, the worse this will become.

Marc Espie <marc.espie.open...@gmail.com> wrote:

> 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