Sat Aug 7 06:44:08 2010 UTC ()
wait[pid]() is called in several places.
If we encounter an error and run the .ERROR target, we may
reap a pid which jobs is waiting for.  Ensure that we
cleanup so that make isn't left waiting for an already
deceased child.


(sjg)
diff -r1.79 -r1.80 src/usr.bin/make/compat.c
diff -r1.152 -r1.153 src/usr.bin/make/job.c
diff -r1.188 -r1.189 src/usr.bin/make/main.c
diff -r1.59 -r1.60 src/usr.bin/make/nonints.h

cvs diff -r1.79 -r1.80 src/usr.bin/make/compat.c (expand / switch to context diff)
--- src/usr.bin/make/compat.c 2010/06/03 15:40:15 1.79
+++ src/usr.bin/make/compat.c 2010/08/07 06:44:08 1.80
@@ -1,4 +1,4 @@
-/*	$NetBSD: compat.c,v 1.79 2010/06/03 15:40:15 sjg Exp $	*/
+/*	$NetBSD: compat.c,v 1.80 2010/08/07 06:44:08 sjg 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.79 2010/06/03 15:40:15 sjg Exp $";
+static char rcsid[] = "$NetBSD: compat.c,v 1.80 2010/08/07 06:44:08 sjg 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.79 2010/06/03 15:40:15 sjg Exp $");
+__RCSID("$NetBSD: compat.c,v 1.80 2010/08/07 06:44:08 sjg Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -381,6 +381,8 @@
     while (1) {
 
 	while ((retstat = wait(&reason)) != cpid) {
+	    if (retstat > 0)
+		JobReapChild(retstat, reason, FALSE); /* not ours? */
 	    if (retstat == -1 && errno != EINTR) {
 		break;
 	    }

cvs diff -r1.152 -r1.153 src/usr.bin/make/job.c (expand / switch to context diff)
--- src/usr.bin/make/job.c 2010/07/20 16:39:27 1.152
+++ src/usr.bin/make/job.c 2010/08/07 06:44:08 1.153
@@ -1,4 +1,4 @@
-/*	$NetBSD: job.c,v 1.152 2010/07/20 16:39:27 christos Exp $	*/
+/*	$NetBSD: job.c,v 1.153 2010/08/07 06:44:08 sjg 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.152 2010/07/20 16:39:27 christos Exp $";
+static char rcsid[] = "$NetBSD: job.c,v 1.153 2010/08/07 06:44:08 sjg 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.152 2010/07/20 16:39:27 christos Exp $");
+__RCSID("$NetBSD: job.c,v 1.153 2010/08/07 06:44:08 sjg Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -344,7 +344,7 @@
 
 static void JobChildSig(int);
 static void JobContinueSig(int);
-static Job *JobFindPid(int, int);
+static Job *JobFindPid(int, int, Boolean);
 static int JobPrintCommand(void *, void *);
 static int JobSaveCommand(void *, void *);
 static void JobClose(Job *);
@@ -616,7 +616,7 @@
  *-----------------------------------------------------------------------
  */
 static Job *
-JobFindPid(int pid, int status)
+JobFindPid(int pid, int status, Boolean isJobs)
 {
     Job *job;
 
@@ -624,7 +624,7 @@
 	if ((job->job_state == status) && job->pid == pid)
 	    return job;
     }
-    if (DEBUG(JOB))
+    if (DEBUG(JOB) && isJobs)
 	job_table_dump("no pid");
     return NULL;
 }
@@ -1927,7 +1927,6 @@
 Job_CatchChildren(void)
 {
     int    	  pid;	    	/* pid of dead child */
-    Job		  *job;	    	/* job descriptor for dead child */
     int	  	  status;   	/* Exit/termination status */
 
     /*
@@ -1941,41 +1940,60 @@
 	    (void)fprintf(debug_file, "Process %d exited/stopped status %x.\n", pid,
 	      status);
 	}
+	JobReapChild(pid, status, TRUE);
+    }
+}
 
-	job = JobFindPid(pid, JOB_ST_RUNNING);
-	if (job == NULL) {
+/*
+ * It is possible that wait[pid]() was called from elsewhere,
+ * this lets us reap jobs regardless.
+ */
+void
+JobReapChild(pid_t pid, int status, Boolean isJobs)
+{
+    Job		  *job;	    	/* job descriptor for dead child */
+
+    /*
+     * Don't even bother if we know there's no one around.
+     */
+    if (jobTokensRunning == 0)
+	return;
+
+    job = JobFindPid(pid, JOB_ST_RUNNING, isJobs);
+    if (job == NULL) {
+	if (isJobs) {
 	    if (!lurking_children)
 		Error("Child (%d) status %x not in table?", pid, status);
-	    continue;
 	}
-	if (WIFSTOPPED(status)) {
-	    if (DEBUG(JOB)) {
-		(void)fprintf(debug_file, "Process %d (%s) stopped.\n",
-				job->pid, job->node->name);
+	return;				/* not ours */
+    }
+    if (WIFSTOPPED(status)) {
+	if (DEBUG(JOB)) {
+	    (void)fprintf(debug_file, "Process %d (%s) stopped.\n",
+			  job->pid, job->node->name);
+	}
+	if (!make_suspended) {
+	    switch (WSTOPSIG(status)) {
+	    case SIGTSTP:
+		(void)printf("*** [%s] Suspended\n", job->node->name);
+		break;
+	    case SIGSTOP:
+		(void)printf("*** [%s] Stopped\n", job->node->name);
+		break;
+	    default:
+		(void)printf("*** [%s] Stopped -- signal %d\n",
+			     job->node->name, WSTOPSIG(status));
 	    }
-	    if (!make_suspended) {
-		    switch (WSTOPSIG(status)) {
-		    case SIGTSTP:
-			(void)printf("*** [%s] Suspended\n", job->node->name);
-			break;
-		    case SIGSTOP:
-			(void)printf("*** [%s] Stopped\n", job->node->name);
-			break;
-		    default:
-			(void)printf("*** [%s] Stopped -- signal %d\n",
-			    job->node->name, WSTOPSIG(status));
-		    }
-		    job->job_suspended = 1;
-	    }
-	    (void)fflush(stdout);
-	    continue;
+	    job->job_suspended = 1;
 	}
+	(void)fflush(stdout);
+	return;
+    }
 
-	job->job_state = JOB_ST_FINISHED;
-	job->exit_status = status;
+    job->job_state = JOB_ST_FINISHED;
+    job->exit_status = status;
 
-	JobFinish(job, status);
-    }
+    JobFinish(job, status);
 }
 
 /*-

cvs diff -r1.188 -r1.189 src/usr.bin/make/main.c (expand / switch to context diff)
--- src/usr.bin/make/main.c 2010/06/03 15:40:16 1.188
+++ src/usr.bin/make/main.c 2010/08/07 06:44:08 1.189
@@ -1,4 +1,4 @@
-/*	$NetBSD: main.c,v 1.188 2010/06/03 15:40:16 sjg Exp $	*/
+/*	$NetBSD: main.c,v 1.189 2010/08/07 06:44:08 sjg Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -69,7 +69,7 @@
  */
 
 #ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: main.c,v 1.188 2010/06/03 15:40:16 sjg Exp $";
+static char rcsid[] = "$NetBSD: main.c,v 1.189 2010/08/07 06:44:08 sjg Exp $";
 #else
 #include <sys/cdefs.h>
 #ifndef lint
@@ -81,7 +81,7 @@
 #if 0
 static char sccsid[] = "@(#)main.c	8.3 (Berkeley) 3/19/94";
 #else
-__RCSID("$NetBSD: main.c,v 1.188 2010/06/03 15:40:16 sjg Exp $");
+__RCSID("$NetBSD: main.c,v 1.189 2010/08/07 06:44:08 sjg Exp $");
 #endif
 #endif /* not lint */
 #endif
@@ -1641,9 +1641,10 @@
 	/*
 	 * Wait for the process to exit.
 	 */
-	while(((pid = waitpid(cpid, &status, 0)) != cpid) && (pid >= 0))
+	while(((pid = waitpid(cpid, &status, 0)) != cpid) && (pid >= 0)) {
+	    JobReapChild(pid, status, FALSE);
 	    continue;
-
+	}
 	cc = Buf_Size(&buf);
 	res = Buf_Destroy(&buf, FALSE);
 

cvs diff -r1.59 -r1.60 src/usr.bin/make/Attic/nonints.h (expand / switch to context diff)
--- src/usr.bin/make/Attic/nonints.h 2010/06/03 15:40:16 1.59
+++ src/usr.bin/make/Attic/nonints.h 2010/08/07 06:44:08 1.60
@@ -1,4 +1,4 @@
-/*	$NetBSD: nonints.h,v 1.59 2010/06/03 15:40:16 sjg Exp $	*/
+/*	$NetBSD: nonints.h,v 1.60 2010/08/07 06:44:08 sjg Exp $	*/
 
 /*-
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -105,6 +105,9 @@
 int For_Eval(char *);
 int For_Accum(char *);
 void For_Run(int);
+
+/* job.c */
+void JobReapChild(pid_t, int, Boolean);
 
 /* main.c */
 void Main_ParseArgLine(const char *);