Module Name: src
Committed By: christos
Date: Wed Feb 6 16:36:01 UTC 2013
Modified Files:
src/usr.bin/make: job.c
Log Message:
fix broken logic:
- poll can return EINTR, it is not restartable like read/write
- check poll return
- it does not make sense to check readyfd() is nready < 0
- check read return
- always call Job_CatchChildren, it is harmless
- short circuit scanning of the poll array if we got all the ready descriptors
To generate a diff of this commit:
cvs rdiff -u -r1.168 -r1.169 src/usr.bin/make/job.c
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/job.c
diff -u src/usr.bin/make/job.c:1.168 src/usr.bin/make/job.c:1.169
--- src/usr.bin/make/job.c:1.168 Sat Feb 2 10:24:08 2013
+++ src/usr.bin/make/job.c Wed Feb 6 11:36:01 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: job.c,v 1.168 2013/02/02 15:24:08 christos Exp $ */
+/* $NetBSD: job.c,v 1.169 2013/02/06 16:36:01 christos 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.168 2013/02/02 15:24:08 christos Exp $";
+static char rcsid[] = "$NetBSD: job.c,v 1.169 2013/02/06 16:36:01 christos 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.168 2013/02/02 15:24:08 christos Exp $");
+__RCSID("$NetBSD: job.c,v 1.169 2013/02/06 16:36:01 christos Exp $");
#endif
#endif /* not lint */
#endif
@@ -139,6 +139,7 @@ __RCSID("$NetBSD: job.c,v 1.168 2013/02/
#include <sys/time.h>
#include <sys/wait.h>
+#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#ifndef USE_SELECT
@@ -2040,38 +2041,50 @@ Job_CatchOutput(void)
{
int nready;
Job *job;
- int i, n;
+ int i;
(void)fflush(stdout);
/* The first fd in the list is the job token pipe */
- nready = poll(fds + 1 - wantToken, nfds - 1 + wantToken, POLL_MSEC);
+ do {
+ nready = poll(fds + 1 - wantToken, nfds - 1 + wantToken, POLL_MSEC);
+ } while (nready < 0 && errno == EINTR);
+
+ if (nready < 0)
+ Punt("poll: %s", strerror(errno));
- if (nready < 0 || readyfd(&childExitJob)) {
+ if (nready > 0 && readyfd(&childExitJob)) {
char token = 0;
- nready -= 1;
- for (n = 0; n < 5 &&
- read(childExitJob.inPipe, &token, 1) == -1 && errno == EAGAIN; n++)
- continue;
- if (token == DO_JOB_RESUME[0])
- /* Complete relay requested from our SIGCONT handler */
- JobRestartJobs();
- Job_CatchChildren();
+ ssize_t count;
+ count = read(childExitJob.inPipe, &token, 1);
+ switch (count) {
+ case 0:
+ Punt("unexpected eof on token pipe");
+ case -1:
+ Punt("token pipe read: %s", strerror(errno));
+ case 1:
+ if (token == DO_JOB_RESUME[0])
+ /* Complete relay requested from our SIGCONT handler */
+ JobRestartJobs();
+ break;
+ default:
+ abort();
+ }
+ --nready;
}
- if (nready <= 0)
- return;
-
- if (wantToken && readyfd(&tokenWaitJob))
- nready--;
+ Job_CatchChildren();
+ if (nready == 0)
+ return;
for (i = 2; i < nfds; i++) {
if (!fds[i].revents)
continue;
job = jobfds[i];
- if (job->job_state != JOB_ST_RUNNING)
- continue;
- JobDoOutput(job, FALSE);
+ if (job->job_state == JOB_ST_RUNNING)
+ JobDoOutput(job, FALSE);
+ if (--nready == 0)
+ return;
}
}