summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrillig <rillig@pkgsrc.org>2007-03-15 09:41:22 +0000
committerrillig <rillig@pkgsrc.org>2007-03-15 09:41:22 +0000
commit5a7bce0e5e1ce28402d9977d5f035e92b7a1f8e7 (patch)
tree66469fd984cf870220d7eba15b2e16f02d380d30
parent79ebe94e429674d4f186fa0728c41027c3ef48df (diff)
downloadpkgsrc-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.c14
-rw-r--r--devel/bmake/files/job.c71
-rw-r--r--devel/bmake/files/job.h3
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_ */