]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
safe_fork: unblock most signals before waiting for child
authorMike Gilbert <floppym@gentoo.org>
Mon, 10 Feb 2020 22:17:02 +0000 (17:17 -0500)
committerMike Gilbert <floppym@gentoo.org>
Mon, 9 Mar 2020 20:58:43 +0000 (16:58 -0400)
This ensures we will recieve SIGTSTP if the user presses Ctrl-Z.

We continue blocking SIGCHLD to ensure the child is processed by
wait_for_terminate_and_check.

Fixes: https://github.com/systemd/systemd/issues/9806
src/basic/process-util.c

index 5de366f830e81b3c21815591fe6f565d42eea82f..4914da6c0b42739d859c802a0931493e215d1fcb 100644 (file)
@@ -1187,7 +1187,7 @@ int safe_fork_full(
 
         pid_t original_pid, pid;
         sigset_t saved_ss, ss;
-        bool block_signals = false;
+        bool block_signals = false, block_all = false;
         int prio, r;
 
         /* A wrapper around fork(), that does a couple of important initializations in addition to mere forking. Always
@@ -1202,7 +1202,7 @@ int safe_fork_full(
                  * be sure that SIGTERMs are not lost we might send to the child. */
 
                 assert_se(sigfillset(&ss) >= 0);
-                block_signals = true;
+                block_signals = block_all = true;
 
         } else if (flags & FORK_WAIT) {
                 /* Let's block SIGCHLD at least, so that we can safely watch for the child process */
@@ -1234,6 +1234,13 @@ int safe_fork_full(
                 log_debug("Successfully forked off '%s' as PID " PID_FMT ".", strna(name), pid);
 
                 if (flags & FORK_WAIT) {
+                        if (block_all) {
+                                /* undo everything except SIGCHLD */
+                                ss = saved_ss;
+                                assert_se(sigaddset(&ss, SIGCHLD) >= 0);
+                                (void) sigprocmask(SIG_SETMASK, &ss, NULL);
+                        }
+
                         r = wait_for_terminate_and_check(name, pid, (flags & FORK_LOG ? WAIT_LOG : 0));
                         if (r < 0)
                                 return r;