Only need to take action on SIGCHLD in parent if no I/O logger.

If there is an I/O logger we will receive ECONNRESET or EPIPE when
we try to read from the socketpair.
This commit is contained in:
Todd C. Miller
2010-04-10 10:31:47 -04:00
parent 32672c1f1a
commit 711b8d1c04

View File

@@ -509,36 +509,27 @@ script_execve(struct command_details *details, char *argv[], char *envp[],
zero_bytes(&input, sizeof(input));
zero_bytes(&output, sizeof(output));
for (;;) {
/* Wait for children as needed. */
if (recvsig[SIGCHLD]) {
pid_t pid;
int flags = WNOHANG;
/*
* If logging I/O, child is the intermediate process,
* otherwise it is the command itself.
*/
recvsig[SIGCHLD] = FALSE;
if (log_io)
flags |= WUNTRACED;
do {
pid = waitpid(child, &child_status, flags);
pid = waitpid(child, &child_status, WNOHANG);
} while (pid == -1 && errno == EINTR);
if (pid == child) {
/*
* If there is no I/O logger we are done. Otherwise,
* we wait for ECONNRESET or EPIPE from the socketpair.
*/
if (!log_io)
recvsig[SIGCHLD] = TRUE; /* XXX - hacky, see below */
else if (WIFSTOPPED(child_status))
recvsig[WSTOPSIG(child_status)] = TRUE;
/* If not logging I/O and child has exited we are done. */
if (!log_io) {
cstat->type = CMD_WSTATUS;
cstat->val = child_status;
return 0;
}
}
}
/* If not logging I/O and child has exited we are done. */
if (!log_io && recvsig[SIGCHLD]) {
cstat->type = CMD_WSTATUS;
cstat->val = child_status;
break;
}
zero_bytes(fdsw, howmany(maxfd + 1, NFDBITS) * sizeof(fd_mask));
zero_bytes(fdsr, howmany(maxfd + 1, NFDBITS) * sizeof(fd_mask));