From: Todd C. Miller Date: Tue, 27 May 2014 16:16:49 +0000 (-0600) Subject: Handle EINTR from write(2) when writing to pipes and socket pairs. X-Git-Tag: SUDO_1_8_11^2~183 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d628e17eaddb1c2fbedaab62f6eb4cd07183ed68;p=sudo Handle EINTR from write(2) when writing to pipes and socket pairs. --- diff --git a/src/exec.c b/src/exec.c index d63de548a..fcf353d40 100644 --- a/src/exec.c +++ b/src/exec.c @@ -877,7 +877,10 @@ handler(int s, siginfo_t *info, void *context) * The pipe is non-blocking, if we overflow the kernel's pipe * buffer we drop the signal. This is not a problem in practice. */ - ignore_result(write(signal_pipe[1], &signo, sizeof(signo))); + while (write(signal_pipe[1], &signo, sizeof(signo)) == -1) { + if (errno != EINTR) + break; + } } #else void @@ -889,7 +892,10 @@ handler(int s) * The pipe is non-blocking, if we overflow the kernel's pipe * buffer we drop the signal. This is not a problem in practice. */ - ignore_result(write(signal_pipe[1], &signo, sizeof(signo))); + while (write(signal_pipe[1], &signo, sizeof(signo)) == -1) { + if (errno != EINTR) + break; + } } #endif @@ -911,7 +917,10 @@ handler_user_only(int s, siginfo_t *info, void *context) * The pipe is non-blocking, if we overflow the kernel's pipe * buffer we drop the signal. This is not a problem in practice. */ - ignore_result(write(signal_pipe[1], &signo, sizeof(signo))); + while (write(signal_pipe[1], &signo, sizeof(signo)) == -1) { + if (errno != EINTR) + break; + } } } #endif /* SA_SIGINFO */ diff --git a/src/exec_pty.c b/src/exec_pty.c index ba3a9b22d..77ed418ec 100644 --- a/src/exec_pty.c +++ b/src/exec_pty.c @@ -148,7 +148,10 @@ mon_handler(int s, siginfo_t *info, void *context) * The pipe is non-blocking, if we overflow the kernel's pipe * buffer we drop the signal. This is not a problem in practice. */ - ignore_result(write(signal_pipe[1], &signo, sizeof(signo))); + while (write(signal_pipe[1], &signo, sizeof(signo)) == -1) { + if (errno != EINTR) + break; + } } #else static void @@ -160,7 +163,10 @@ mon_handler(int s) * The pipe is non-blocking, if we overflow the kernel's pipe * buffer we drop the signal. This is not a problem in practice. */ - ignore_result(write(signal_pipe[1], &signo, sizeof(signo))); + while (write(signal_pipe[1], &signo, sizeof(signo)) == -1) { + if (errno != EINTR) + break; + } } #endif @@ -1281,7 +1287,10 @@ exec_monitor(struct command_details *details, int backchannel) /* setup tty and exec command */ exec_pty(details, &cstat, errpipe[1]); - ignore_result(write(errpipe[1], &cstat, sizeof(cstat))); + while (write(errpipe[1], &cstat, sizeof(cstat)) == -1) { + if (errno != EINTR) + break; + } _exit(1); } close(errpipe[1]); diff --git a/src/signal.c b/src/signal.c index 6ae41f597..54377ea9c 100644 --- a/src/signal.c +++ b/src/signal.c @@ -102,7 +102,10 @@ sudo_handler(int signo) * The pipe is non-blocking, if we overflow the kernel's pipe * buffer we drop the signal. This is not a problem in practice. */ - ignore_result(write(signal_pipe[1], &signo, sizeof(signo))); + while (write(signal_pipe[1], &signo, sizeof(signo)) == -1) { + if (errno != EINTR) + break; + } } /*