chiark / gitweb /
src/jobclient.c: Cope if the jobserver pipe is set nonblocking.
authorMark Wooding <mdw@distorted.org.uk>
Sun, 19 Apr 2020 17:47:31 +0000 (18:47 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 19 Apr 2020 17:51:18 +0000 (18:51 +0100)
The GNU Make manual says this doesn't happen, but the source code and
actual behaviour say differently.

src/jobclient.c

index bc8d85890da59a767a9f0ed81a5afaa49820c6da..02141d4718098b0a916851c27a002ca54197ae31 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <sys/select.h>
 #include <unistd.h>
 
 #define PY_SSIZE_T_CLEAN
@@ -52,6 +53,7 @@ static PyObject *pymeth_jobclient(PyObject *me, PyObject *arg)
   PyObject *rc = 0;
   struct sigaction sa, oldsa;
   sigset_t mask, oldmask;
+  fd_set infd;
   int rstrchld = 0;
   int fd, sfd;
   int kid, st;
@@ -101,7 +103,11 @@ again:
    * like this happens, then we go back and try reaping children again.
    */
   Py_BEGIN_ALLOW_THREADS
-  n = read(sigfd, &ch, 1);
+  for (;;) {
+    n = read(sigfd, &ch, 1); if (n >= 0 || errno != EAGAIN) break;
+    FD_ZERO(&infd); FD_SET(sigfd, &infd);
+    n = select(sigfd + 1, &infd, 0, 0, 0); if (n < 0) break;
+  }
   Py_END_ALLOW_THREADS
   if (n == 1) rc = Py_BuildValue("(cOO)", ch, Py_None, Py_None);
   else if (!n) rc = Py_BuildValue("(sOO)", "", Py_None, Py_None);