block signals before fork()ing the pipestream child
authorPhilipp Gesang <philipp.gesang@intra2net.com>
Mon, 12 Feb 2018 08:19:53 +0000 (09:19 +0100)
committerPhilipp Gesang <philipp.gesang@intra2net.com>
Tue, 14 Aug 2018 14:53:34 +0000 (16:53 +0200)
Block all signals until we are ready to handle them again.

In particular, this saves us checking for close(2) being
interrupted.

src/pipestream.cpp

index b9cdcf7..7a89be2 100644 (file)
@@ -249,6 +249,7 @@ inpipebuf::init_without_shell (const char *const *argv,
 {
     FILE *pipeobj = NULL;
     int pipefd [2];
+    sigset_t oldmask, newmask;
 
     if (!out && !err) {
         errno = EINVAL;
@@ -260,10 +261,14 @@ inpipebuf::init_without_shell (const char *const *argv,
         PIPE_CTOR_FAIL("pipe");
     }
 
+    sigfillset (&newmask);
+    sigprocmask (SIG_SETMASK, &newmask, &oldmask);
+
     errno = 0;
     pid_t childpid = fork ();
     switch (childpid) {
         case -1: {
+            sigprocmask (SIG_SETMASK, &oldmask, NULL);
             PIPE_CTOR_FAIL("fork");
             break;
         }
@@ -292,6 +297,8 @@ inpipebuf::init_without_shell (const char *const *argv,
 
             close (pipefd [1]);
 
+            sigprocmask (SIG_SETMASK, &oldmask, NULL);
+
             errno = 0;
             if (path) {
                 execvpe (argv [0], const_cast <char *const *>(argv), environ);
@@ -304,6 +311,8 @@ inpipebuf::init_without_shell (const char *const *argv,
         default: {
             close (pipefd [1]);
 
+            sigprocmask (SIG_SETMASK, &oldmask, NULL);
+
             errno = 0;
             if ((pipeobj = fdopen (pipefd [0], "r")) == NULL) {
                 PIPE_CTOR_FAIL("fdopen");