]> 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:03:44 +0000 (13:03 -0400)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Mon, 26 Jul 2010 17:03:44 +0000 (13:03 -0400)
a pty that has gone away.  Fixes bugzilla 422

--HG--
branch : 1.7

exec_pty.c

index af034d56624598e836154481a07a82fa036bd476..ca607472d47aebc529d5231da9a45c72bb56c140 100644 (file)
@@ -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;