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;
     }
 }
 

Reply via email to