]> granicus.if.org Git - sudo/commitdiff
Handle ENXIO from read/write which can occur when reading/writing
authorTodd C. Miller <Todd.Miller@courtesan.com>
Mon, 26 Jul 2010 17:04:11 +0000 (13:04 -0400)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Mon, 26 Jul 2010 17:04:11 +0000 (13:04 -0400)
a pty that has gone away.

src/exec_pty.c

index d73b005affcb3d708964bb0de3e0e2023f1616c7..165e3dc33fbb3ea93fc80c02fbdf3696eccd13cc 100644 (file)
@@ -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;