diff options
author | rillig <rillig@pkgsrc.org> | 2007-03-15 09:41:22 +0000 |
---|---|---|
committer | rillig <rillig@pkgsrc.org> | 2007-03-15 09:41:22 +0000 |
commit | 5a7bce0e5e1ce28402d9977d5f035e92b7a1f8e7 (patch) | |
tree | 66469fd984cf870220d7eba15b2e16f02d380d30 | |
parent | 79ebe94e429674d4f186fa0728c41027c3ef48df (diff) | |
download | pkgsrc-5a7bce0e5e1ce28402d9977d5f035e92b7a1f8e7.tar.gz |
On IRIX, the command line is limited to about 20000 characters. The new
function Job_Execv executes a shell command line, and if that fails due
to an overly long command line, the shell command is written into a
temporary file, which is then executed.
This is at least necessary to make the bulk builds work on IRIX.
-rw-r--r-- | devel/bmake/files/compat.c | 14 | ||||
-rw-r--r-- | devel/bmake/files/job.c | 71 | ||||
-rw-r--r-- | devel/bmake/files/job.h | 3 |
3 files changed, 74 insertions, 14 deletions
diff --git a/devel/bmake/files/compat.c b/devel/bmake/files/compat.c index 4de01f63a57..3d7d792bd3a 100644 --- a/devel/bmake/files/compat.c +++ b/devel/bmake/files/compat.c @@ -1,4 +1,4 @@ -/* $NetBSD: compat.c,v 1.1.1.1 2005/12/02 00:02:59 sjg Exp $ */ +/* $NetBSD: compat.c,v 1.2 2007/03/15 09:41:22 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. @@ -70,14 +70,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: compat.c,v 1.1.1.1 2005/12/02 00:02:59 sjg Exp $"; +static char rcsid[] = "$NetBSD: compat.c,v 1.2 2007/03/15 09:41:22 rillig Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)compat.c 8.2 (Berkeley) 3/19/94"; #else -__RCSID("$NetBSD: compat.c,v 1.1.1.1 2005/12/02 00:02:59 sjg Exp $"); +__RCSID("$NetBSD: compat.c,v 1.2 2007/03/15 09:41:22 rillig Exp $"); #endif #endif /* not lint */ #endif @@ -220,8 +220,6 @@ CompatRunCommand(ClientData cmdp, ClientData gnp) 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, ClientData gnp) 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, ClientData gnp) } 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 **)UNCONST(av)); execError("exec", av[0]); _exit(1); } diff --git a/devel/bmake/files/job.c b/devel/bmake/files/job.c index 79a59aecc9c..66f1600769a 100644 --- a/devel/bmake/files/job.c +++ b/devel/bmake/files/job.c @@ -1,4 +1,4 @@ -/* $NetBSD: job.c,v 1.2 2005/11/02 18:16:04 tv Exp $ */ +/* $NetBSD: job.c,v 1.3 2007/03/15 09:41:22 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. @@ -70,14 +70,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: job.c,v 1.2 2005/11/02 18:16:04 tv Exp $"; +static char rcsid[] = "$NetBSD: job.c,v 1.3 2007/03/15 09:41:22 rillig Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94"; #else -__RCSID("$NetBSD: job.c,v 1.2 2005/11/02 18:16:04 tv Exp $"); +__RCSID("$NetBSD: job.c,v 1.3 2007/03/15 09:41:22 rillig Exp $"); #endif #endif /* not lint */ #endif @@ -136,6 +136,8 @@ __RCSID("$NetBSD: job.c,v 1.2 2005/11/02 18:16:04 tv Exp $"); * 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, int timeout) 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); +} diff --git a/devel/bmake/files/job.h b/devel/bmake/files/job.h index 4e2f53efd47..499731ddbb2 100644 --- a/devel/bmake/files/job.h +++ b/devel/bmake/files/job.h @@ -1,4 +1,4 @@ -/* $NetBSD: job.h,v 1.1.1.1 2005/12/02 00:03:00 sjg Exp $ */ +/* $NetBSD: job.h,v 1.2 2007/03/15 09:41:22 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. @@ -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_ */ |