hush: fix incorrect PS2 dispaly and trap handling while reading command
The fix affects only !ENABLE_FEATURE_EDITING configuration Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
29c54aa9f9
commit
b8709032a3
27
shell/hush.c
27
shell/hush.c
@ -1319,6 +1319,8 @@ static void restore_G_args(save_arg_t *sv, char **argv)
|
||||
* "echo $$; sleep 5 & wait; ls -l" + "kill -INT <pid>"
|
||||
* Example 3: this does not wait 5 sec, but executes ls:
|
||||
* "sleep 5; ls -l" + press ^C
|
||||
* Example 4: this does not wait and does not execute ls:
|
||||
* "sleep 5 & wait; ls -l" + press ^C
|
||||
*
|
||||
* (What happens to signals which are IGN on shell start?)
|
||||
* (What happens with signal mask on shell start?)
|
||||
@ -1471,13 +1473,13 @@ static int check_and_run_traps(int sig)
|
||||
int last_sig = 0;
|
||||
|
||||
if (sig)
|
||||
goto jump_in;
|
||||
goto got_sig;
|
||||
|
||||
while (1) {
|
||||
sig = sigtimedwait(&G.blocked_set, NULL, &zero_timespec);
|
||||
if (sig <= 0)
|
||||
break;
|
||||
jump_in:
|
||||
last_sig = sig;
|
||||
got_sig:
|
||||
if (G.traps && G.traps[sig]) {
|
||||
if (G.traps[sig][0]) {
|
||||
/* We have user-defined handler */
|
||||
@ -1488,6 +1490,7 @@ static int check_and_run_traps(int sig)
|
||||
save_rcode = G.last_exitcode;
|
||||
builtin_eval(argv);
|
||||
G.last_exitcode = save_rcode;
|
||||
last_sig = sig;
|
||||
} /* else: "" trap, ignoring signal */
|
||||
continue;
|
||||
}
|
||||
@ -1503,6 +1506,7 @@ static int check_and_run_traps(int sig)
|
||||
/* Builtin was ^C'ed, make it look prettier: */
|
||||
bb_putchar('\n');
|
||||
G.flag_SIGINT = 1;
|
||||
last_sig = sig;
|
||||
break;
|
||||
#if ENABLE_HUSH_JOB
|
||||
case SIGHUP: {
|
||||
@ -1521,6 +1525,11 @@ static int check_and_run_traps(int sig)
|
||||
#endif
|
||||
default: /* ignored: */
|
||||
/* SIGTERM, SIGQUIT, SIGTTIN, SIGTTOU, SIGTSTP */
|
||||
/* note:
|
||||
* we dont do 'last_sig = sig' here -> NOT returning this sig.
|
||||
* example: wait is not interrupted by TERM
|
||||
* in interactive shell, because TERM is ignored.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1921,11 +1930,18 @@ static void get_user_input(struct in_str *i)
|
||||
# else
|
||||
do {
|
||||
G.flag_SIGINT = 0;
|
||||
fputs(prompt_str, stdout);
|
||||
if (i->last_char == '\0' || i->last_char == '\n') {
|
||||
/* Why check_and_run_traps here? Try this interactively:
|
||||
* $ trap 'echo INT' INT; (sleep 2; kill -INT $$) &
|
||||
* $ <[enter], repeatedly...>
|
||||
* Without check_and_run_traps, handler never runs.
|
||||
*/
|
||||
check_and_run_traps(0);
|
||||
fputs(prompt_str, stdout);
|
||||
}
|
||||
fflush_all();
|
||||
G.user_input_buf[0] = r = fgetc(i->file);
|
||||
/*G.user_input_buf[1] = '\0'; - already is and never changed */
|
||||
//do we need check_and_run_traps(0)? (maybe only if stdin)
|
||||
} while (G.flag_SIGINT);
|
||||
i->eof_flag = (r == EOF);
|
||||
# endif
|
||||
@ -3322,6 +3338,7 @@ static char *fetch_till_str(o_string *as_string,
|
||||
int ch;
|
||||
|
||||
goto jump_in;
|
||||
|
||||
while (1) {
|
||||
ch = i_getch(input);
|
||||
if (ch != EOF)
|
||||
|
Loading…
Reference in New Issue
Block a user