aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-08-02 16:37:39 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2017-08-02 16:37:39 +0200
commit7c40ddd9500907925041131374cb43eb87ef5494 (patch)
tree415676f7439a3c42e2137f357c8e8904a93007cc /shell
parent95f7953f2c46c7b9c799250aa8dc6eb10cc5c726 (diff)
downloadbusybox-w32-7c40ddd9500907925041131374cb43eb87ef5494.tar.gz
busybox-w32-7c40ddd9500907925041131374cb43eb87ef5494.tar.bz2
busybox-w32-7c40ddd9500907925041131374cb43eb87ef5494.zip
NOFORK fixes
"rm -i FILE" and "yes" can now be interrupted by ^C in hush. This also now works: $ usleep 19999999 ^C $ echo $? 130 function old new delta run_pipe 1668 1711 +43 pseudo_exec_argv 312 321 +9 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/0 up/down: 52/0) Total: 52 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
-rw-r--r--shell/hush.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 9f946d82f..cfefb7324 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -7363,6 +7363,8 @@ static NOINLINE void pseudo_exec_argv(nommu_save_t *nommu_save,
7363 */ 7363 */
7364 close_saved_fds_and_FILE_fds(); 7364 close_saved_fds_and_FILE_fds();
7365//FIXME: should also close saved redir fds 7365//FIXME: should also close saved redir fds
7366 /* Without this, "rm -i FILE" can't be ^C'ed: */
7367 switch_off_special_sigs(G.special_sig_mask);
7366 debug_printf_exec("running applet '%s'\n", argv[0]); 7368 debug_printf_exec("running applet '%s'\n", argv[0]);
7367 run_applet_no_and_exit(a, argv[0], argv); 7369 run_applet_no_and_exit(a, argv[0], argv);
7368 } 7370 }
@@ -8045,6 +8047,24 @@ static NOINLINE int run_pipe(struct pipe *pi)
8045 add_vars(old_vars); 8047 add_vars(old_vars);
8046/* clean_up_and_ret0: */ 8048/* clean_up_and_ret0: */
8047 restore_redirects(squirrel); 8049 restore_redirects(squirrel);
8050 /*
8051 * Try "usleep 99999999" + ^C + "echo $?"
8052 * with FEATURE_SH_NOFORK=y.
8053 */
8054 if (!funcp) {
8055 /* It was builtin or nofork.
8056 * if this would be a real fork/execed program,
8057 * it should have died if a fatal sig was received.
8058 * But OTOH, there was no separate process,
8059 * the sig was sent to _shell_, not to non-existing
8060 * child.
8061 * Let's just handle ^C only, this one is obvious:
8062 * we aren't ok with exitcode 0 when ^C was pressed
8063 * during builtin/nofork.
8064 */
8065 if (sigismember(&G.pending_set, SIGINT))
8066 rcode = 128 + SIGINT;
8067 }
8048 clean_up_and_ret1: 8068 clean_up_and_ret1:
8049 free(argv_expanded); 8069 free(argv_expanded);
8050 IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;) 8070 IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
@@ -8060,6 +8080,14 @@ static NOINLINE int run_pipe(struct pipe *pi)
8060 if (rcode == 0) { 8080 if (rcode == 0) {
8061 debug_printf_exec(": run_nofork_applet '%s' '%s'...\n", 8081 debug_printf_exec(": run_nofork_applet '%s' '%s'...\n",
8062 argv_expanded[0], argv_expanded[1]); 8082 argv_expanded[0], argv_expanded[1]);
8083 /*
8084 * Note: signals (^C) can't interrupt here.
8085 * We remember them and they will be acted upon
8086 * after applet returns.
8087 * This makes applets which can run for a long time
8088 * and/or wait for user input ineligible for NOFORK:
8089 * for example, "yes" or "rm" (rm -i waits for input).
8090 */
8063 rcode = run_nofork_applet(n, argv_expanded); 8091 rcode = run_nofork_applet(n, argv_expanded);
8064 } 8092 }
8065 goto clean_up_and_ret; 8093 goto clean_up_and_ret;
@@ -8491,7 +8519,7 @@ static int run_list(struct pipe *pi)
8491 G.last_bg_pid = pi->cmds[pi->num_cmds - 1].pid; 8519 G.last_bg_pid = pi->cmds[pi->num_cmds - 1].pid;
8492 G.last_bg_pid_exitcode = 0; 8520 G.last_bg_pid_exitcode = 0;
8493 debug_printf_exec(": cmd&: exitcode EXIT_SUCCESS\n"); 8521 debug_printf_exec(": cmd&: exitcode EXIT_SUCCESS\n");
8494/* Check pi->pi_inverted? "! sleep 1 & echo $?": bash says 1. dash and ash says 0 */ 8522/* Check pi->pi_inverted? "! sleep 1 & echo $?": bash says 1. dash and ash say 0 */
8495 rcode = EXIT_SUCCESS; 8523 rcode = EXIT_SUCCESS;
8496 goto check_traps; 8524 goto check_traps;
8497 } else { 8525 } else {
@@ -10178,6 +10206,7 @@ static int wait_for_child_or_signal(struct pipe *waitfor_pipe, pid_t waitfor_pid
10178 /* So, did we get a signal? */ 10206 /* So, did we get a signal? */
10179 sig = check_and_run_traps(); 10207 sig = check_and_run_traps();
10180 if (sig /*&& sig != SIGCHLD - always true */) { 10208 if (sig /*&& sig != SIGCHLD - always true */) {
10209 /* Do this for any (non-ignored) signal, not only for ^C */
10181 ret = 128 + sig; 10210 ret = 128 + sig;
10182 break; 10211 break;
10183 } 10212 }