Module Name:    src
Committed By:   sjg
Date:           Sat Aug  7 06:44:08 UTC 2010

Modified Files:
        src/usr.bin/make: compat.c job.c main.c nonints.h

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.79 -r1.80 src/usr.bin/make/compat.c
cvs rdiff -u -r1.152 -r1.153 src/usr.bin/make/job.c
cvs rdiff -u -r1.188 -r1.189 src/usr.bin/make/main.c
cvs rdiff -u -r1.59 -r1.60 src/usr.bin/make/nonints.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/make/compat.c
diff -u src/usr.bin/make/compat.c:1.79 src/usr.bin/make/compat.c:1.80
--- src/usr.bin/make/compat.c:1.79	Thu Jun  3 15:40:15 2010
+++ src/usr.bin/make/compat.c	Sat Aug  7 06:44:08 2010
@@ -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;
 	    }

Index: src/usr.bin/make/job.c
diff -u src/usr.bin/make/job.c:1.152 src/usr.bin/make/job.c:1.153
--- src/usr.bin/make/job.c:1.152	Tue Jul 20 16:39:27 2010
+++ src/usr.bin/make/job.c	Sat Aug  7 06:44:08 2010
@@ -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);
+    }
+}
+
+/*
+ * 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);
-	if (job == NULL) {
+    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);
-	    }
-	    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;
+	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));
 	    }
-	    (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);
 }
 
 /*-

Index: src/usr.bin/make/main.c
diff -u src/usr.bin/make/main.c:1.188 src/usr.bin/make/main.c:1.189
--- src/usr.bin/make/main.c:1.188	Thu Jun  3 15:40:16 2010
+++ src/usr.bin/make/main.c	Sat Aug  7 06:44:08 2010
@@ -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);
 

Index: src/usr.bin/make/nonints.h
diff -u src/usr.bin/make/nonints.h:1.59 src/usr.bin/make/nonints.h:1.60
--- src/usr.bin/make/nonints.h:1.59	Thu Jun  3 15:40:16 2010
+++ src/usr.bin/make/nonints.h	Sat Aug  7 06:44:08 2010
@@ -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
@@ -106,6 +106,9 @@
 int For_Accum(char *);
 void For_Run(int);
 
+/* job.c */
+void JobReapChild(pid_t, int, Boolean);
+
 /* main.c */
 void Main_ParseArgLine(const char *);
 void MakeMode(const char *);

Reply via email to