summaryrefslogtreecommitdiff
path: root/shell/shell_common.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-05-11 11:49:21 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2011-05-11 11:49:21 +0200
commit10c0131a8a1b3db7fd6b23b72ebd7b33afc7b018 (patch)
tree88b6afcd3614a43db767780f48a288d868cf2289 /shell/shell_common.c
parent12bc152b31420c3e3d441c87a995fe7b65dd23fe (diff)
downloadbusybox-w32-10c0131a8a1b3db7fd6b23b72ebd7b33afc7b018.tar.gz
busybox-w32-10c0131a8a1b3db7fd6b23b72ebd7b33afc7b018.tar.bz2
busybox-w32-10c0131a8a1b3db7fd6b23b72ebd7b33afc7b018.zip
hush: use SA_RESTARTed signal handlers across read.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell/shell_common.c')
-rw-r--r--shell/shell_common.c34
1 files changed, 21 insertions, 13 deletions
diff --git a/shell/shell_common.c b/shell/shell_common.c
index a5c455c8e..bbc22ed34 100644
--- a/shell/shell_common.c
+++ b/shell/shell_common.c
@@ -159,32 +159,40 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val),
159 bufpos = 0; 159 bufpos = 0;
160 do { 160 do {
161 char c; 161 char c;
162 struct pollfd pfd[1];
163 int timeout;
162 164
163 errno = 0; 165 if ((bufpos & 0xff) == 0)
166 buffer = xrealloc(buffer, bufpos + 0x100);
164 167
168 timeout = -1;
165 if (end_ms) { 169 if (end_ms) {
166 int timeout;
167 struct pollfd pfd[1];
168
169 pfd[0].fd = fd;
170 pfd[0].events = POLLIN;
171 timeout = end_ms - (unsigned)monotonic_ms(); 170 timeout = end_ms - (unsigned)monotonic_ms();
172 if (timeout <= 0 /* already late? */ 171 if (timeout <= 0) { /* already late? */
173 || poll(pfd, 1, timeout) != 1 /* no? wait... */
174 ) { /* timed out! */
175 err = errno;
176 retval = (const char *)(uintptr_t)1; 172 retval = (const char *)(uintptr_t)1;
177 goto ret; 173 goto ret;
178 } 174 }
179 } 175 }
180 176
181 if ((bufpos & 0xff) == 0) 177 /* We must poll even if timeout is -1:
182 buffer = xrealloc(buffer, bufpos + 0x100); 178 * we want to be interrupted if signal arrives,
183 if (nonblock_immune_read(fd, &buffer[bufpos], 1, /*loop_on_EINTR:*/ 0) != 1) { 179 * regardless of SA_RESTART-ness of that signal!
180 */
181 errno = 0;
182 pfd[0].fd = fd;
183 pfd[0].events = POLLIN;
184 if (poll(pfd, 1, timeout) != 1) {
185 /* timed out, or EINTR */
186 err = errno;
187 retval = (const char *)(uintptr_t)1;
188 goto ret;
189 }
190 if (read(fd, &buffer[bufpos], 1) != 1) {
184 err = errno; 191 err = errno;
185 retval = (const char *)(uintptr_t)1; 192 retval = (const char *)(uintptr_t)1;
186 break; 193 break;
187 } 194 }
195
188 c = buffer[bufpos]; 196 c = buffer[bufpos];
189 if (c == '\0') 197 if (c == '\0')
190 continue; 198 continue;