aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-05-08 21:20:01 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2011-05-08 21:20:01 +0200
commitb8709032a3fb57b3ec536bdf9b92b526ed63b995 (patch)
tree2dea5e1de762aa127a3bb5b031ff1f2704fbf4fb
parent29c54aa9f9e8eedf2d227550a790e76661ce63ad (diff)
downloadbusybox-w32-b8709032a3fb57b3ec536bdf9b92b526ed63b995.tar.gz
busybox-w32-b8709032a3fb57b3ec536bdf9b92b526ed63b995.tar.bz2
busybox-w32-b8709032a3fb57b3ec536bdf9b92b526ed63b995.zip
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>
-rw-r--r--shell/hush.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/shell/hush.c b/shell/hush.c
index d3e957c2f..bcd458427 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -1319,6 +1319,8 @@ static void restore_G_args(save_arg_t *sv, char **argv)
1319 * "echo $$; sleep 5 & wait; ls -l" + "kill -INT <pid>" 1319 * "echo $$; sleep 5 & wait; ls -l" + "kill -INT <pid>"
1320 * Example 3: this does not wait 5 sec, but executes ls: 1320 * Example 3: this does not wait 5 sec, but executes ls:
1321 * "sleep 5; ls -l" + press ^C 1321 * "sleep 5; ls -l" + press ^C
1322 * Example 4: this does not wait and does not execute ls:
1323 * "sleep 5 & wait; ls -l" + press ^C
1322 * 1324 *
1323 * (What happens to signals which are IGN on shell start?) 1325 * (What happens to signals which are IGN on shell start?)
1324 * (What happens with signal mask on shell start?) 1326 * (What happens with signal mask on shell start?)
@@ -1471,13 +1473,13 @@ static int check_and_run_traps(int sig)
1471 int last_sig = 0; 1473 int last_sig = 0;
1472 1474
1473 if (sig) 1475 if (sig)
1474 goto jump_in; 1476 goto got_sig;
1477
1475 while (1) { 1478 while (1) {
1476 sig = sigtimedwait(&G.blocked_set, NULL, &zero_timespec); 1479 sig = sigtimedwait(&G.blocked_set, NULL, &zero_timespec);
1477 if (sig <= 0) 1480 if (sig <= 0)
1478 break; 1481 break;
1479 jump_in: 1482 got_sig:
1480 last_sig = sig;
1481 if (G.traps && G.traps[sig]) { 1483 if (G.traps && G.traps[sig]) {
1482 if (G.traps[sig][0]) { 1484 if (G.traps[sig][0]) {
1483 /* We have user-defined handler */ 1485 /* We have user-defined handler */
@@ -1488,6 +1490,7 @@ static int check_and_run_traps(int sig)
1488 save_rcode = G.last_exitcode; 1490 save_rcode = G.last_exitcode;
1489 builtin_eval(argv); 1491 builtin_eval(argv);
1490 G.last_exitcode = save_rcode; 1492 G.last_exitcode = save_rcode;
1493 last_sig = sig;
1491 } /* else: "" trap, ignoring signal */ 1494 } /* else: "" trap, ignoring signal */
1492 continue; 1495 continue;
1493 } 1496 }
@@ -1503,6 +1506,7 @@ static int check_and_run_traps(int sig)
1503 /* Builtin was ^C'ed, make it look prettier: */ 1506 /* Builtin was ^C'ed, make it look prettier: */
1504 bb_putchar('\n'); 1507 bb_putchar('\n');
1505 G.flag_SIGINT = 1; 1508 G.flag_SIGINT = 1;
1509 last_sig = sig;
1506 break; 1510 break;
1507#if ENABLE_HUSH_JOB 1511#if ENABLE_HUSH_JOB
1508 case SIGHUP: { 1512 case SIGHUP: {
@@ -1521,6 +1525,11 @@ static int check_and_run_traps(int sig)
1521#endif 1525#endif
1522 default: /* ignored: */ 1526 default: /* ignored: */
1523 /* SIGTERM, SIGQUIT, SIGTTIN, SIGTTOU, SIGTSTP */ 1527 /* SIGTERM, SIGQUIT, SIGTTIN, SIGTTOU, SIGTSTP */
1528 /* note:
1529 * we dont do 'last_sig = sig' here -> NOT returning this sig.
1530 * example: wait is not interrupted by TERM
1531 * in interactive shell, because TERM is ignored.
1532 */
1524 break; 1533 break;
1525 } 1534 }
1526 } 1535 }
@@ -1921,11 +1930,18 @@ static void get_user_input(struct in_str *i)
1921# else 1930# else
1922 do { 1931 do {
1923 G.flag_SIGINT = 0; 1932 G.flag_SIGINT = 0;
1924 fputs(prompt_str, stdout); 1933 if (i->last_char == '\0' || i->last_char == '\n') {
1934 /* Why check_and_run_traps here? Try this interactively:
1935 * $ trap 'echo INT' INT; (sleep 2; kill -INT $$) &
1936 * $ <[enter], repeatedly...>
1937 * Without check_and_run_traps, handler never runs.
1938 */
1939 check_and_run_traps(0);
1940 fputs(prompt_str, stdout);
1941 }
1925 fflush_all(); 1942 fflush_all();
1926 G.user_input_buf[0] = r = fgetc(i->file); 1943 G.user_input_buf[0] = r = fgetc(i->file);
1927 /*G.user_input_buf[1] = '\0'; - already is and never changed */ 1944 /*G.user_input_buf[1] = '\0'; - already is and never changed */
1928//do we need check_and_run_traps(0)? (maybe only if stdin)
1929 } while (G.flag_SIGINT); 1945 } while (G.flag_SIGINT);
1930 i->eof_flag = (r == EOF); 1946 i->eof_flag = (r == EOF);
1931# endif 1947# endif
@@ -3322,6 +3338,7 @@ static char *fetch_till_str(o_string *as_string,
3322 int ch; 3338 int ch;
3323 3339
3324 goto jump_in; 3340 goto jump_in;
3341
3325 while (1) { 3342 while (1) {
3326 ch = i_getch(input); 3343 ch = i_getch(input);
3327 if (ch != EOF) 3344 if (ch != EOF)