script: exit if reading from pseudo-tty errors out (do not loop)
authorDenis Vlasenko <vda.linux@googlemail.com>
Tue, 6 May 2008 19:11:41 +0000 (19:11 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Tue, 6 May 2008 19:11:41 +0000 (19:11 -0000)
function                                             old     new   delta
script_main                                          991     966     -25

util-linux/script.c

index 5d6f4d924ae8b5678e58fb66e22dad81009ebb5f..63d3039d32eb8c02b533e72b4274b9e0db6d005e 100644 (file)
@@ -99,13 +99,12 @@ int script_main(int argc ATTRIBUTE_UNUSED, char **argv)
                /* parent */
 #define buf bb_common_bufsiz1
                struct pollfd pfd[2];
-               struct pollfd *ppfd = pfd;
                int outfd, count, loop;
 
                outfd = xopen(fname, mode);
-               pfd[0].fd = 0;
+               pfd[0].fd = pty;
                pfd[0].events = POLLIN;
-               pfd[1].fd = pty;
+               pfd[1].fd = 0;
                pfd[1].events = POLLIN;
                ndelay_on(pty); /* this descriptor is not shared, can do this */
                /* ndelay_on(0); - NO, stdin can be shared! Pity :( */
@@ -115,29 +114,17 @@ int script_main(int argc ATTRIBUTE_UNUSED, char **argv)
                /* TODO: don't use full_write's, use proper write buffering */
                while (fd_count) {
                        /* not safe_poll! we want SIGCHLD to EINTR poll */
-                       if (poll(ppfd, fd_count, -1) < 0 && errno != EINTR) {
+                       if (poll(pfd, fd_count, -1) < 0 && errno != EINTR) {
                                /* If child exits too quickly, we may get EIO:
                                 * for example, try "script -c true" */
                                break;
                        }
                        if (pfd[0].revents) {
-                               count = safe_read(0, buf, sizeof(buf));
-                               if (count <= 0) {
-                                       /* err/eof: don't read anymore */
-                                       pfd[0].revents = 0;
-                                       ppfd++;
-                                       fd_count--;
-                               } else {
-                                       full_write(pty, buf, count);
-                               }
-                       }
-                       if (pfd[1].revents) {
                                errno = 0;
                                count = safe_read(pty, buf, sizeof(buf));
                                if (count <= 0 && errno != EAGAIN) {
-                                       /* err/eof: don't read anymore */
-                                       pfd[1].revents = 0;
-                                       fd_count--;
+                                       /* err/eof from pty: exit */
+                                       goto restore;
                                }
                                if (count > 0) {
                                        full_write(1, buf, count);
@@ -147,6 +134,16 @@ int script_main(int argc ATTRIBUTE_UNUSED, char **argv)
                                        }
                                }
                        }
+                       if (pfd[1].revents) {
+                               count = safe_read(0, buf, sizeof(buf));
+                               if (count <= 0) {
+                                       /* err/eof from stdin: don't read stdin anymore */
+                                       pfd[1].revents = 0;
+                                       fd_count--;
+                               } else {
+                                       full_write(pty, buf, count);
+                               }
+                       }
                }
                /* If loop was exited because SIGCHLD handler set fd_count to 0,
                 * there still can be some buffered output. But not loop forever:
@@ -161,7 +158,7 @@ int script_main(int argc ATTRIBUTE_UNUSED, char **argv)
                        full_write(1, buf, count);
                        full_write(outfd, buf, count);
                }
-
+ restore:
                if (attr_ok == 0)
                        tcsetattr(0, TCSAFLUSH, &tt);
                if (!(opt & 8)) /* not -q */