From 20167fb74e6cb8f172289cf97c995d531c2a9187 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 20 Jan 2009 16:06:59 -0800 Subject: [PATCH] process: Avoid stealing pclose()'s exit status. When we use popen() and pclose(), pclose() wants to return the process's exit status, but it can't if the SIGCHLD handler gets it first. So, instead of asking for any child process exit status in sigchld_handler(), only ask for the exit status of registered PIDs. --- lib/process.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/lib/process.c b/lib/process.c index d787b7bf9..087ca6b87 100644 --- a/lib/process.c +++ b/lib/process.c @@ -337,21 +337,22 @@ process_wait(struct process *p) static void sigchld_handler(int signr UNUSED) { - for (;;) { - struct process *p; - int status; - pid_t pid; - - pid = waitpid(-1, &status, WNOHANG); - if (pid <= 0) { - break; - } + struct process *p; - LIST_FOR_EACH (p, struct process, node, &all_processes) { - if (p->pid == pid) { + LIST_FOR_EACH (p, struct process, node, &all_processes) { + if (!p->exited) { + int retval, status; + do { + retval = waitpid(p->pid, &status, WNOHANG); + } while (retval == -1 && errno == EINTR); + if (retval == p->pid) { p->exited = true; p->status = status; - break; + } else if (retval < 0) { + /* XXX We want to log something but we're in a signal + * handler. */ + p->exited = true; + p->status = -1; } } } -- 2.47.0