This patch is needed to make the pkgsrc bulk builds work on IRIX, which has a very low limit for the length of the command line (20k). See also: * http://wiki.netbsd.se/index.php/How_to_do_an_unprivileged_bulk_build_on_IRIX Index: job.h =================================================================== RCS file: /cvsroot/pkgsrc/devel/bmake/files/job.h,v retrieving revision 1.1 diff -u -p -r1.1 job.h --- job.h 31 Oct 2005 21:34:24 -0000 1.1 +++ job.h 22 Feb 2007 19:18:20 -0000 @@ -313,5 +313,6 @@ void Job_TokenReturn(void); void Job_TokenFlush(void); Boolean Job_TokenWithdraw(void); void Job_ServerStart(int); +void Job_Execv(const char *, char **); #endif /* _JOB_H_ */ Index: job.c =================================================================== RCS file: /cvsroot/pkgsrc/devel/bmake/files/job.c,v retrieving revision 1.2 diff -u -p -r1.2 job.c --- job.c 2 Nov 2005 18:16:04 -0000 1.2 +++ job.c 22 Feb 2007 19:18:23 -0000 @@ -136,6 +136,8 @@ __RCSID("$NetBSD: job.c,v 1.2 2005/11/02 * Job_Touch Update a target without really updating it. * * Job_Wait Wait for all currently-running jobs to finish. + * + * Job_Execv Execute a shell job. */ #ifdef HAVE_CONFIG_H @@ -1567,7 +1569,7 @@ JobExec(Job *job, char **argv) } else #endif /* REMOTE */ { - (void)execv(shellPath, argv); + Job_Execv(shellPath, argv); execError("exec", shellPath); } _exit(1); @@ -3753,3 +3755,64 @@ emul_poll(struct pollfd *fd, int nfd, in return npoll; } #endif /* USE_SELECT */ + +/*- + *----------------------------------------------------------------------- + * Job_Execv -- + * execute a shell job. + * + * Results: + * Executes a shell with the given arguments. If the command is too + * long, writes it into a temporary file and executes that. + * + * Does not return if the job could be executed. + * + * Side Effects: + * May modify argv[]. + * + *----------------------------------------------------------------------- + */ +void Job_Execv(const char *argv0, char **argv) +{ + FILE *tfile; + char cmd[2 + sizeof(TMPPAT)]; /* ". /tmpname" */ + size_t len; + int argc, tfd; + char *tmpfname; + + /* Try to execute the command. */ + (void)execv(argv0, argv); + if (errno != E2BIG) + return; + + /* + * The command line is too long, so save it into a temporary + * file and run the shell with that file. + */ + + /* Assume that the last argument is the shell command. */ + argc = 0; + while (argv[argc]) + argc++; + + (void)strcpy(cmd, ". "); + (void)strcat(cmd, TMPPAT); + tmpfname = cmd + 2; + + if ((tfd = mkstemp(tmpfname)) == -1) + Punt("Could not create temporary file %s: %s", tmpfname, strerror(errno)); + + tfile = fdopen(tfd, "w"); + if (tfile == NULL) + Punt("fdopen: %s", strerror(errno)); + + len = strlen(argv[argc - 1]); + if (fwrite(argv[argc - 1], 1, len, tfile) != len + || fputc('\n', tfile) == EOF + || fclose(tfile) != 0) + Punt("Could not write to %s: %s", tmpfname, strerror(errno)); + argv[argc - 1] = cmd; + + /* Now try again. */ + (void)execv(argv0, argv); +} Index: compat.c =================================================================== RCS file: /cvsroot/pkgsrc/devel/bmake/files/compat.c,v retrieving revision 1.1 diff -u -p -r1.1 compat.c --- compat.c 31 Oct 2005 21:34:24 -0000 1.1 +++ compat.c 22 Feb 2007 19:18:23 -0000 @@ -220,8 +220,6 @@ CompatRunCommand(ClientData cmdp, Client const char **av; /* Argument vector for thing to exec */ int argc; /* Number of arguments in av or 0 if not * dynamically allocated */ - Boolean local; /* TRUE if command should be executed - * locally */ char *cmd = (char *)cmdp; GNode *gn = (GNode *)gnp; @@ -339,8 +337,6 @@ CompatRunCommand(ClientData cmdp, Client av = (const char **)brk_string(cmd, &argc, TRUE, &bp); } - local = TRUE; - /* * Fork and execute the single command. If the fork fails, we abort. */ @@ -350,10 +346,10 @@ CompatRunCommand(ClientData cmdp, Client } if (cpid == 0) { Check_Cwd(av); - if (local) + if (*cp == '\0') (void)execvp(av[0], (char *const *)UNCONST(av)); else - (void)execv(av[0], (char *const *)UNCONST(av)); + Job_Execv(av[0], (char *const *)UNCONST(av)); execError("exec", av[0]); _exit(1); }