From: Todd C. Miller Date: Mon, 26 Jul 2010 17:03:44 +0000 (-0400) Subject: Handle ENXIO from read/write which can occur when reading/writing X-Git-Tag: SUDO_1_7_4~24 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=13cff351118e8d64bed317d4a88d2a54adbe8f34;p=sudo Handle ENXIO from read/write which can occur when reading/writing a pty that has gone away. Fixes bugzilla 422 --HG-- branch : 1.7 --- diff --git a/exec_pty.c b/exec_pty.c index af034d566..ca607472d 100644 --- a/exec_pty.c +++ b/exec_pty.c @@ -287,17 +287,25 @@ perform_io(fdsr, fdsw, cstat) n = read(iob->rfd, iob->buf + iob->len, sizeof(iob->buf) - iob->len); } while (n == -1 && errno == EINTR); - if (n == -1) { - if (errno != EAGAIN) + switch (n) { + case -1: + if (errno == EAGAIN) + break; + if (errno != ENXIO && errno != EBADF) { + errors++; + break; + } + /* FALLTHROUGH */ + case 0: + /* got EOF or pty has gone away */ + safe_close(iob->rfd); + iob->rfd = -1; + break; + default: + if (!iob->action(iob->buf + iob->len, n)) + terminate_child(child, TRUE); + iob->len += n; break; - } else if (n == 0) { - /* got EOF */ - safe_close(iob->rfd); - iob->rfd = -1; - } else { - if (!iob->action(iob->buf + iob->len, n)) - terminate_child(child, TRUE); - iob->len += n; } } if (iob->wfd != -1 && FD_ISSET(iob->wfd, fdsw)) { @@ -306,8 +314,8 @@ perform_io(fdsr, fdsw, cstat) iob->len - iob->off); } while (n == -1 && errno == EINTR); if (n == -1) { - if (errno == EPIPE) { - /* other end of pipe closed */ + if (errno == EPIPE || errno == ENXIO || errno == EBADF) { + /* other end of pipe closed or pty revoked */ if (iob->rfd != -1) { safe_close(iob->rfd); iob->rfd = -1;