From 23c96fbc2eb7deaeef2ab0774f5f2d150f4be853 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Mon, 26 Jul 2010 13:04:11 -0400 Subject: [PATCH] Handle ENXIO from read/write which can occur when reading/writing a pty that has gone away. --- src/exec_pty.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/exec_pty.c b/src/exec_pty.c index d73b005af..165e3dc33 100644 --- a/src/exec_pty.c +++ b/src/exec_pty.c @@ -403,17 +403,25 @@ perform_io(fd_set *fdsr, fd_set *fdsw, struct command_status *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)) { @@ -422,8 +430,8 @@ perform_io(fd_set *fdsr, fd_set *fdsw, struct command_status *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;