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.
This commit is contained in:
Todd C. Miller
2011-03-09 11:28:51 -05:00
parent da24fe8c3b
commit caefd1abdc

View File

@@ -328,8 +328,6 @@ sudo_execve(struct command_details *details, char *argv[], char *envp[],
goto done; goto done;
} }
if (n == -1) { if (n == -1) {
if (errno == EAGAIN || errno == EINTR)
continue;
/* Error reading signal_pipe[0], should not happen. */ /* Error reading signal_pipe[0], should not happen. */
break; break;
} }
@@ -404,7 +402,7 @@ done:
/* /*
* Read signals on fd written to by handler(). * 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 static int
handle_signals(int fd, pid_t child, int log_io, struct command_status *cstat) 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. */ /* It should not be possible to get EOF but just in case. */
if (nread == 0) if (nread == 0)
errno = ECONNRESET; errno = ECONNRESET;
if (errno != EINTR && errno != EAGAIN) { /* Restart if interrupted by signal so the pipe doesn't fill. */
sudo_debug(9, "error reading signal pipe %s", strerror(errno)); if (errno == EINTR)
cstat->type = CMD_ERRNO; continue;
cstat->val = errno; /* 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; return -1;
} }
sudo_debug(9, "received signal %d", signo); sudo_debug(9, "received signal %d", signo);