[git commit] hush: fix incorrect PS2 dispaly and trap handling while reading command

Denys Vlasenko vda.linux at googlemail.com
Sun May 8 19:20:01 UTC 2011


commit: http://git.busybox.net/busybox/commit/?id=b8709032a3fb57b3ec536bdf9b92b526ed63b995
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

The fix affects only !ENABLE_FEATURE_EDITING configuration

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 shell/hush.c |   27 ++++++++++++++++++++++-----
 1 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/shell/hush.c b/shell/hush.c
index d3e957c..bcd4584 100644
--- a/shell/hush.c
+++ b/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)
-- 
1.7.3.4



More information about the busybox-cvs mailing list