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
--- 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;
}
--- 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);
}
/*-
--- 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);
--- 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 *);