From caefd1abdc9227f6865f34f93bd05fef76f01ebf Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Wed, 9 Mar 2011 11:28:51 -0500 Subject: [PATCH] In handle_signals(), restart the read() on EINTR to make sure we keep up with the signal pipe. Don't return -1 on EAGAIN, it just means we have emptied the pipe. --- src/exec.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/exec.c b/src/exec.c index 139d04a00..baa4e3f02 100644 --- a/src/exec.c +++ b/src/exec.c @@ -328,8 +328,6 @@ sudo_execve(struct command_details *details, char *argv[], char *envp[], goto done; } if (n == -1) { - if (errno == EAGAIN || errno == EINTR) - continue; /* Error reading signal_pipe[0], should not happen. */ break; } @@ -404,7 +402,7 @@ done: /* * Read signals on fd written to by handler(). - * Returns -1 on error (possibly non-fatal), 0 on child exit, else 1. + * Returns -1 on error, 0 on child exit, else 1. */ static int handle_signals(int fd, pid_t child, int log_io, struct command_status *cstat) @@ -421,11 +419,15 @@ handle_signals(int fd, pid_t child, int log_io, struct command_status *cstat) /* It should not be possible to get EOF but just in case. */ if (nread == 0) errno = ECONNRESET; - if (errno != EINTR && errno != EAGAIN) { - sudo_debug(9, "error reading signal pipe %s", strerror(errno)); - cstat->type = CMD_ERRNO; - cstat->val = errno; - } + /* Restart if interrupted by signal so the pipe doesn't fill. */ + if (errno == EINTR) + continue; + /* If pipe is empty, we are done. */ + if (errno == EAGAIN) + break; + sudo_debug(9, "error reading signal pipe %s", strerror(errno)); + cstat->type = CMD_ERRNO; + cstat->val = errno; return -1; } sudo_debug(9, "received signal %d", signo);