diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-05-06 19:11:41 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-05-06 19:11:41 +0000 |
| commit | 06ebc16461fcb1cbf54ac0b5d73d08225fe83f22 (patch) | |
| tree | d29c8d04cfb8e331981bf02d2b4c7f41c0727d73 /util-linux | |
| parent | dddfaff36354050d170bcc1d1328cc23e5b0065e (diff) | |
| download | busybox-w32-06ebc16461fcb1cbf54ac0b5d73d08225fe83f22.tar.gz busybox-w32-06ebc16461fcb1cbf54ac0b5d73d08225fe83f22.tar.bz2 busybox-w32-06ebc16461fcb1cbf54ac0b5d73d08225fe83f22.zip | |
script: exit if reading from pseudo-tty errors out (do not loop)
function old new delta
script_main 991 966 -25
Diffstat (limited to 'util-linux')
| -rw-r--r-- | util-linux/script.c | 35 |
1 files changed, 16 insertions, 19 deletions
diff --git a/util-linux/script.c b/util-linux/script.c index 5d6f4d924..63d3039d3 100644 --- a/util-linux/script.c +++ b/util-linux/script.c | |||
| @@ -99,13 +99,12 @@ int script_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
| 99 | /* parent */ | 99 | /* parent */ |
| 100 | #define buf bb_common_bufsiz1 | 100 | #define buf bb_common_bufsiz1 |
| 101 | struct pollfd pfd[2]; | 101 | struct pollfd pfd[2]; |
| 102 | struct pollfd *ppfd = pfd; | ||
| 103 | int outfd, count, loop; | 102 | int outfd, count, loop; |
| 104 | 103 | ||
| 105 | outfd = xopen(fname, mode); | 104 | outfd = xopen(fname, mode); |
| 106 | pfd[0].fd = 0; | 105 | pfd[0].fd = pty; |
| 107 | pfd[0].events = POLLIN; | 106 | pfd[0].events = POLLIN; |
| 108 | pfd[1].fd = pty; | 107 | pfd[1].fd = 0; |
| 109 | pfd[1].events = POLLIN; | 108 | pfd[1].events = POLLIN; |
| 110 | ndelay_on(pty); /* this descriptor is not shared, can do this */ | 109 | ndelay_on(pty); /* this descriptor is not shared, can do this */ |
| 111 | /* ndelay_on(0); - NO, stdin can be shared! Pity :( */ | 110 | /* ndelay_on(0); - NO, stdin can be shared! Pity :( */ |
| @@ -115,29 +114,17 @@ int script_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
| 115 | /* TODO: don't use full_write's, use proper write buffering */ | 114 | /* TODO: don't use full_write's, use proper write buffering */ |
| 116 | while (fd_count) { | 115 | while (fd_count) { |
| 117 | /* not safe_poll! we want SIGCHLD to EINTR poll */ | 116 | /* not safe_poll! we want SIGCHLD to EINTR poll */ |
| 118 | if (poll(ppfd, fd_count, -1) < 0 && errno != EINTR) { | 117 | if (poll(pfd, fd_count, -1) < 0 && errno != EINTR) { |
| 119 | /* If child exits too quickly, we may get EIO: | 118 | /* If child exits too quickly, we may get EIO: |
| 120 | * for example, try "script -c true" */ | 119 | * for example, try "script -c true" */ |
| 121 | break; | 120 | break; |
| 122 | } | 121 | } |
| 123 | if (pfd[0].revents) { | 122 | if (pfd[0].revents) { |
| 124 | count = safe_read(0, buf, sizeof(buf)); | ||
| 125 | if (count <= 0) { | ||
| 126 | /* err/eof: don't read anymore */ | ||
| 127 | pfd[0].revents = 0; | ||
| 128 | ppfd++; | ||
| 129 | fd_count--; | ||
| 130 | } else { | ||
| 131 | full_write(pty, buf, count); | ||
| 132 | } | ||
| 133 | } | ||
| 134 | if (pfd[1].revents) { | ||
| 135 | errno = 0; | 123 | errno = 0; |
| 136 | count = safe_read(pty, buf, sizeof(buf)); | 124 | count = safe_read(pty, buf, sizeof(buf)); |
| 137 | if (count <= 0 && errno != EAGAIN) { | 125 | if (count <= 0 && errno != EAGAIN) { |
| 138 | /* err/eof: don't read anymore */ | 126 | /* err/eof from pty: exit */ |
| 139 | pfd[1].revents = 0; | 127 | goto restore; |
| 140 | fd_count--; | ||
| 141 | } | 128 | } |
| 142 | if (count > 0) { | 129 | if (count > 0) { |
| 143 | full_write(1, buf, count); | 130 | full_write(1, buf, count); |
| @@ -147,6 +134,16 @@ int script_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
| 147 | } | 134 | } |
| 148 | } | 135 | } |
| 149 | } | 136 | } |
| 137 | if (pfd[1].revents) { | ||
| 138 | count = safe_read(0, buf, sizeof(buf)); | ||
| 139 | if (count <= 0) { | ||
| 140 | /* err/eof from stdin: don't read stdin anymore */ | ||
| 141 | pfd[1].revents = 0; | ||
| 142 | fd_count--; | ||
| 143 | } else { | ||
| 144 | full_write(pty, buf, count); | ||
| 145 | } | ||
| 146 | } | ||
| 150 | } | 147 | } |
| 151 | /* If loop was exited because SIGCHLD handler set fd_count to 0, | 148 | /* If loop was exited because SIGCHLD handler set fd_count to 0, |
| 152 | * there still can be some buffered output. But not loop forever: | 149 | * there still can be some buffered output. But not loop forever: |
| @@ -161,7 +158,7 @@ int script_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
| 161 | full_write(1, buf, count); | 158 | full_write(1, buf, count); |
| 162 | full_write(outfd, buf, count); | 159 | full_write(outfd, buf, count); |
| 163 | } | 160 | } |
| 164 | 161 | restore: | |
| 165 | if (attr_ok == 0) | 162 | if (attr_ok == 0) |
| 166 | tcsetattr(0, TCSAFLUSH, &tt); | 163 | tcsetattr(0, TCSAFLUSH, &tt); |
| 167 | if (!(opt & 8)) /* not -q */ | 164 | if (!(opt & 8)) /* not -q */ |
