diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2020-12-23 23:44:55 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2020-12-23 23:44:55 +0100 |
commit | 521220ed1aa63e53e2f30042ae8f00f683e2254d (patch) | |
tree | b3e8e0925b2826dfad4b47e93f022cd192308742 | |
parent | 18bcaf374cc8eb7bb1db22a1163dc7d38ee6c7c0 (diff) | |
download | busybox-521220ed1aa63e53e2f30042ae8f00f683e2254d.tar.gz |
hush: fix ^C in INTERACTIVE, !EDITING config
function old new delta
refill_HFILE_and_getc 88 170 +82
fgetc_interactive 226 250 +24
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 106/0) Total: 106 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/hush.c | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/shell/hush.c b/shell/hush.c index e0b519217..d3444c556 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -1649,6 +1649,26 @@ static int refill_HFILE_and_getc(HFILE *fp) /* Already saw EOF */ return EOF; } +#if ENABLE_HUSH_INTERACTIVE && !ENABLE_FEATURE_EDITING + /* If user presses ^C, read() restarts after SIGINT (we use SA_RESTART). + * IOW: ^C will not immediately stop line input. + * But poll() is different: it does NOT restart after signals. + */ + if (fp == G.HFILE_stdin) { + struct pollfd pfd[1]; + pfd[0].fd = fp->fd; + pfd[0].events = POLLIN; + n = poll(pfd, 1, -1); + if (n < 0 + /*&& errno == EINTR - assumed true */ + && sigismember(&G.pending_set, SIGINT) + ) { + return '\0'; + } + } +#else +/* if FEATURE_EDITING=y, we do not use this routine for interactive input */ +#endif /* Try to buffer more input */ n = safe_read(fp->fd, fp->buf, sizeof(fp->buf)); if (n < 0) { @@ -2090,7 +2110,6 @@ static void hush_exit(int exitcode) #endif } - //TODO: return a mask of ALL handled sigs? static int check_and_run_traps(void) { @@ -2665,19 +2684,23 @@ static int get_user_input(struct in_str *i) */ check_and_run_traps(); fputs(prompt_str, stdout); + fflush_all(); } - fflush_all(); -//FIXME: here ^C or SIGINT will have effect only after <Enter> r = hfgetc(i->file); /* In !ENABLE_FEATURE_EDITING we don't use read_line_input, * no ^C masking happens during fgetc, no special code for ^C: * it generates SIGINT as usual. */ check_and_run_traps(); - if (G.flag_SIGINT) - G.last_exitcode = 128 | SIGINT; - if (r != '\0') + if (r != '\0' && !G.flag_SIGINT) break; + if (G.flag_SIGINT) { + /* ^C or SIGINT: repeat */ + /* bash prints ^C even on real SIGINT (non-kbd generated) */ + /* kernel prints "^C" itself, just print newline: */ + write(STDOUT_FILENO, "\n", 1); + G.last_exitcode = 128 | SIGINT; + } } return r; # endif |