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 | |
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
-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 */ |