diff options
Diffstat (limited to 'shell/shell_common.c')
-rw-r--r-- | shell/shell_common.c | 48 |
1 files changed, 31 insertions, 17 deletions
diff --git a/shell/shell_common.c b/shell/shell_common.c index 7fb5f8c58..657f0df8f 100644 --- a/shell/shell_common.c +++ b/shell/shell_common.c | |||
@@ -55,7 +55,7 @@ const char* FAST_FUNC | |||
55 | shell_builtin_read(struct builtin_read_params *params) | 55 | shell_builtin_read(struct builtin_read_params *params) |
56 | { | 56 | { |
57 | struct pollfd pfd[1]; | 57 | struct pollfd pfd[1]; |
58 | #define fd (pfd[0].fd) /* -u FD */ | 58 | #define fd (pfd->fd) /* -u FD */ |
59 | unsigned err; | 59 | unsigned err; |
60 | unsigned end_ms; /* -t TIMEOUT */ | 60 | unsigned end_ms; /* -t TIMEOUT */ |
61 | int nchars; /* -n NUM */ | 61 | int nchars; /* -n NUM */ |
@@ -144,7 +144,7 @@ shell_builtin_read(struct builtin_read_params *params) | |||
144 | * bash seems to ignore -p PROMPT for this use case. | 144 | * bash seems to ignore -p PROMPT for this use case. |
145 | */ | 145 | */ |
146 | int r; | 146 | int r; |
147 | pfd[0].events = POLLIN; | 147 | pfd->events = POLLIN; |
148 | r = poll(pfd, 1, /*timeout:*/ 0); | 148 | r = poll(pfd, 1, /*timeout:*/ 0); |
149 | /* Return 0 only if poll returns 1 ("one fd ready"), else return 1: */ | 149 | /* Return 0 only if poll returns 1 ("one fd ready"), else return 1: */ |
150 | return (const char *)(uintptr_t)(r <= 0); | 150 | return (const char *)(uintptr_t)(r <= 0); |
@@ -209,8 +209,8 @@ shell_builtin_read(struct builtin_read_params *params) | |||
209 | * 32-bit unix time wrapped (year 2038+). | 209 | * 32-bit unix time wrapped (year 2038+). |
210 | */ | 210 | */ |
211 | if (timeout <= 0) { /* already late? */ | 211 | if (timeout <= 0) { /* already late? */ |
212 | retval = (const char *)(uintptr_t)1; | 212 | retval = (const char *)(uintptr_t)2; |
213 | goto ret; | 213 | break; |
214 | } | 214 | } |
215 | } | 215 | } |
216 | 216 | ||
@@ -219,15 +219,23 @@ shell_builtin_read(struct builtin_read_params *params) | |||
219 | * regardless of SA_RESTART-ness of that signal! | 219 | * regardless of SA_RESTART-ness of that signal! |
220 | */ | 220 | */ |
221 | errno = 0; | 221 | errno = 0; |
222 | pfd[0].events = POLLIN; | 222 | pfd->events = POLLIN; |
223 | //TODO race with a signal arriving just before the poll! | 223 | |
224 | #if ENABLE_PLATFORM_MINGW32 | 224 | #if ENABLE_PLATFORM_MINGW32 |
225 | /* Don't poll if timeout is -1, it hurts performance. */ | 225 | /* Don't poll if timeout is -1, it hurts performance. The |
226 | * caution above about interrupts isn't relevant on Windows | ||
227 | * where Ctrl-C causes an event, not a signal. | ||
228 | */ | ||
226 | if (timeout >= 0) | 229 | if (timeout >= 0) |
227 | #endif | 230 | #endif |
228 | if (poll(pfd, 1, timeout) <= 0) { | 231 | /* test bb_got_signal, then poll(), atomically wrt signals */ |
229 | /* timed out, or EINTR */ | 232 | if (check_got_signal_and_poll(pfd, timeout) <= 0) { |
233 | /* timed out, or some error */ | ||
230 | err = errno; | 234 | err = errno; |
235 | if (!err) { /* timed out */ | ||
236 | retval = (const char *)(uintptr_t)2; | ||
237 | break; | ||
238 | } | ||
231 | retval = (const char *)(uintptr_t)1; | 239 | retval = (const char *)(uintptr_t)1; |
232 | goto ret; | 240 | goto ret; |
233 | } | 241 | } |
@@ -238,15 +246,18 @@ shell_builtin_read(struct builtin_read_params *params) | |||
238 | key = windows_read_key(fd, NULL, timeout); | 246 | key = windows_read_key(fd, NULL, timeout); |
239 | if (key == 0x03) { | 247 | if (key == 0x03) { |
240 | /* ^C pressed */ | 248 | /* ^C pressed */ |
241 | retval = (const char *)(uintptr_t)2; | 249 | retval = (const char *)(uintptr_t)3; |
242 | goto ret; | 250 | goto ret; |
243 | } | 251 | } |
244 | else if (key == -1 || (key == 0x1a && bufpos == 0)) { | 252 | else if (key == -1) { |
245 | /* timeout or ^Z at start of buffer */ | 253 | /* timeout */ |
254 | retval = (const char *)(uintptr_t)2; | ||
255 | break; | ||
256 | } else if (key == 0x1a && bufpos == 0) { | ||
257 | /* ^Z at start of buffer */ | ||
246 | retval = (const char *)(uintptr_t)1; | 258 | retval = (const char *)(uintptr_t)1; |
247 | goto ret; | 259 | break; |
248 | } | 260 | } else if (key == '\b') { |
249 | else if (key == '\b') { | ||
250 | if (bufpos > 0) { | 261 | if (bufpos > 0) { |
251 | --bufpos; | 262 | --bufpos; |
252 | ++nchars; | 263 | ++nchars; |
@@ -278,7 +289,7 @@ shell_builtin_read(struct builtin_read_params *params) | |||
278 | * and exit BS context. | 289 | * and exit BS context. |
279 | * - CR LF not in BS context: replace CR with LF */ | 290 | * - CR LF not in BS context: replace CR with LF */ |
280 | buffer[--bufpos] = c; | 291 | buffer[--bufpos] = c; |
281 | ++nchars; | 292 | nchars += 1 + (backslash == 2); |
282 | } | 293 | } |
283 | } else if (backslash == 2) { | 294 | } else if (backslash == 2) { |
284 | /* We saw BS CR ??, keep escaped CR, exit BS context, | 295 | /* We saw BS CR ??, keep escaped CR, exit BS context, |
@@ -298,6 +309,9 @@ shell_builtin_read(struct builtin_read_params *params) | |||
298 | backslash = 0; | 309 | backslash = 0; |
299 | if (c != '\n') | 310 | if (c != '\n') |
300 | goto put; | 311 | goto put; |
312 | #if ENABLE_PLATFORM_MINGW32 | ||
313 | ++nchars; | ||
314 | #endif | ||
301 | continue; | 315 | continue; |
302 | } | 316 | } |
303 | if (c == '\\') { | 317 | if (c == '\\') { |
@@ -338,7 +352,7 @@ shell_builtin_read(struct builtin_read_params *params) | |||
338 | } | 352 | } |
339 | put: | 353 | put: |
340 | bufpos++; | 354 | bufpos++; |
341 | } while (--nchars); | 355 | } while (IF_PLATFORM_MINGW32(backslash ||) --nchars); |
342 | 356 | ||
343 | if (argv[0]) { | 357 | if (argv[0]) { |
344 | /* Remove trailing space $IFS chars */ | 358 | /* Remove trailing space $IFS chars */ |