tech-toolchain archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: make: cannot vfork() twice - on darwin
On Thu, 22 Apr 2010 22:35:00 +0000, David Holland writes:
>On Thu, Apr 22, 2010 at 03:25:53PM -0700, Simon J. Gerraty wrote:
> > This is "cute", only seems to impact darwin so far.
> > We get an error from vfork() if we've already done it
> > (this happens when trying to export a var that uses :sh in the child).
>
>vforking twice is not allowed.
Yes, but everything but darwin it would seem let's you ;-)
> > Index: main.c
>
>How about centralizing the logic, something like
Sounds reasonable, still need to use the pid trick,
since a parent can vfork many children ok, it is the child that cannot
vfork - and should not disturb the parent.
Ok the patch is below.
_BUT_ the change to job.c breaks unit-tests/dotwait
I haven't worked out why. The change to Cmd_Exec() is the one that
fixes darwin. Leaving job.c alone for now.
Index: compat.c
===================================================================
RCS file: /cvsroot/src/usr.bin/make/compat.c,v
retrieving revision 1.77
diff -u -p -r1.77 compat.c
--- compat.c 7 Apr 2010 00:11:27 -0000 1.77
+++ compat.c 22 Apr 2010 23:03:51 -0000
@@ -355,7 +355,7 @@ again:
/*
* Fork and execute the single command. If the fork fails, we abort.
*/
- cpid = vfork();
+ cpid = Fork();
if (cpid < 0) {
Fatal("Could not fork");
}
Index: job.c
===================================================================
RCS file: /cvsroot/src/usr.bin/make/job.c,v
retrieving revision 1.148
diff -u -p -r1.148 job.c
--- job.c 22 Apr 2010 19:11:17 -0000 1.148
+++ job.c 22 Apr 2010 23:03:51 -0000
@@ -1299,7 +1299,7 @@ JobExec(Job *job, char **argv)
/* Pre-emptively mark job running, pid still zero though */
job->job_state = JOB_ST_RUNNING;
- cpid = vfork();
+ cpid = Fork();
if (cpid == -1)
Punt("Cannot vfork: %s", strerror(errno));
Index: main.c
===================================================================
RCS file: /cvsroot/src/usr.bin/make/main.c,v
retrieving revision 1.181
diff -u -p -r1.181 main.c
--- main.c 22 Apr 2010 20:25:16 -0000 1.181
+++ main.c 22 Apr 2010 23:03:52 -0000
@@ -1532,6 +1532,27 @@ Check_Cwd(const char **argv)
}
}
+/*
+ * We cannot vfork() in a child of vfork()
+ * Most systems do not enforce this but some do.
+ */
+pid_t
+Fork(void)
+{
+ static pid_t mypid = 0;
+ pid_t pid;
+
+ pid = getpid();
+ if (!mypid)
+ mypid = pid;
+
+ if (pid == mypid)
+ pid = vfork();
+ else
+ pid = fork();
+ return pid;
+}
+
/*-
* Cmd_Exec --
* Execute the command in cmd, and return the output of that command
@@ -1581,7 +1602,7 @@ Cmd_Exec(const char *cmd, const char **e
/*
* Fork
*/
- switch (cpid = vfork()) {
+ switch (cpid = Fork()) {
case 0:
/*
* Close input side of pipe
Index: nonints.h
===================================================================
RCS file: /cvsroot/src/usr.bin/make/nonints.h,v
retrieving revision 1.58
diff -u -p -r1.58 nonints.h
--- nonints.h 7 Apr 2010 00:11:27 -0000 1.58
+++ nonints.h 22 Apr 2010 23:03:52 -0000
@@ -110,6 +110,7 @@ void For_Run(int);
void Main_ParseArgLine(const char *);
void MakeMode(const char *);
int main(int, char **);
+pid_t Fork(void);
char *Cmd_Exec(const char *, const char **);
void Error(const char *, ...) __attribute__((__format__(__printf__, 1, 2)));
void Fatal(const char *, ...)
Home |
Main Index |
Thread Index |
Old Index