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>
This commit is contained in:
parent
18bcaf374c
commit
521220ed1a
35
shell/hush.c
35
shell/hush.c
@ -1649,6 +1649,26 @@ static int refill_HFILE_and_getc(HFILE *fp)
|
|||||||
/* Already saw EOF */
|
/* Already saw EOF */
|
||||||
return 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 */
|
/* Try to buffer more input */
|
||||||
n = safe_read(fp->fd, fp->buf, sizeof(fp->buf));
|
n = safe_read(fp->fd, fp->buf, sizeof(fp->buf));
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
@ -2090,7 +2110,6 @@ static void hush_exit(int exitcode)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//TODO: return a mask of ALL handled sigs?
|
//TODO: return a mask of ALL handled sigs?
|
||||||
static int check_and_run_traps(void)
|
static int check_and_run_traps(void)
|
||||||
{
|
{
|
||||||
@ -2665,19 +2684,23 @@ static int get_user_input(struct in_str *i)
|
|||||||
*/
|
*/
|
||||||
check_and_run_traps();
|
check_and_run_traps();
|
||||||
fputs(prompt_str, stdout);
|
fputs(prompt_str, stdout);
|
||||||
|
fflush_all();
|
||||||
}
|
}
|
||||||
fflush_all();
|
|
||||||
//FIXME: here ^C or SIGINT will have effect only after <Enter>
|
|
||||||
r = hfgetc(i->file);
|
r = hfgetc(i->file);
|
||||||
/* In !ENABLE_FEATURE_EDITING we don't use read_line_input,
|
/* In !ENABLE_FEATURE_EDITING we don't use read_line_input,
|
||||||
* no ^C masking happens during fgetc, no special code for ^C:
|
* no ^C masking happens during fgetc, no special code for ^C:
|
||||||
* it generates SIGINT as usual.
|
* it generates SIGINT as usual.
|
||||||
*/
|
*/
|
||||||
check_and_run_traps();
|
check_and_run_traps();
|
||||||
if (G.flag_SIGINT)
|
if (r != '\0' && !G.flag_SIGINT)
|
||||||
G.last_exitcode = 128 | SIGINT;
|
|
||||||
if (r != '\0')
|
|
||||||
break;
|
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;
|
return r;
|
||||||
# endif
|
# endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user