aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--util-linux/script.c35
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 */