aboutsummaryrefslogtreecommitdiff
path: root/shell/shell_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'shell/shell_common.c')
-rw-r--r--shell/shell_common.c48
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
55shell_builtin_read(struct builtin_read_params *params) 55shell_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 */