Check if the child terminates before waiting for signals. This avoid the infinite waiting if the child terminates before sigprocmask(). Tested by checking if it can work with a sleep() before sigprocmask(). PiperOrigin-RevId: 834828821
diff --git a/centipede/runner_fork_server.cc b/centipede/runner_fork_server.cc index 0fd7a0a..359128d 100644 --- a/centipede/runner_fork_server.cc +++ b/centipede/runner_fork_server.cc
@@ -310,8 +310,21 @@ if (write(pipe1, &ch, 1) == -1) { Exit("###write ack to pipe1 failed\n"); } + // The child might be already terminated before we call sigprocmask(), so + // check it before waiting for signals. + bool child_terminated = false; int status = -1; - while (true) { + { + const pid_t ret = waitpid(pid, &status, WNOHANG); + if (ret < 0) { + Exit("###initial waitpid failed\n"); + } + if (ret == pid && (WIFEXITED(status) || WIFSIGNALED(status))) { + Log("###Got exit status\n"); + child_terminated = true; + } + } + while (!child_terminated) { int sig = -1; Log("###Waiting for a signal\n"); if (sigwait(&wait_sigset, &sig) != 0) { @@ -330,7 +343,7 @@ } if (ret == pid && (WIFEXITED(status) || WIFSIGNALED(status))) { Log("###Got exit status\n"); - break; + child_terminated = true; } } else { Exit("###Unknown signal from sigwait\n");