diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2011-05-12 13:12:47 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-05-12 13:12:47 +0200 |
commit | 75e77deab11dc976d55197fcd6021030ed323e07 (patch) | |
tree | 866bab5b43960e74bae3e7ab423a54801bc745d3 | |
parent | ebc1ee2e2a243a0ff3de6d2b70406ba75b771fa0 (diff) | |
download | busybox-w32-75e77deab11dc976d55197fcd6021030ed323e07.tar.gz busybox-w32-75e77deab11dc976d55197fcd6021030ed323e07.tar.bz2 busybox-w32-75e77deab11dc976d55197fcd6021030ed323e07.zip |
hush: fixes and small shrink for HUSH_JOB!=y
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/hush.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/shell/hush.c b/shell/hush.c index bb95d6318..132b974f0 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -805,9 +805,9 @@ struct globals { | |||
805 | unsigned special_sig_mask; | 805 | unsigned special_sig_mask; |
806 | #if ENABLE_HUSH_JOB | 806 | #if ENABLE_HUSH_JOB |
807 | unsigned fatal_sig_mask; | 807 | unsigned fatal_sig_mask; |
808 | #define G_fatal_sig_mask G.fatal_sig_mask | 808 | # define G_fatal_sig_mask G.fatal_sig_mask |
809 | #else | 809 | #else |
810 | #define G_fatal_sig_mask 0 | 810 | # define G_fatal_sig_mask 0 |
811 | #endif | 811 | #endif |
812 | char **traps; /* char *traps[NSIG] */ | 812 | char **traps; /* char *traps[NSIG] */ |
813 | sigset_t pending_set; | 813 | sigset_t pending_set; |
@@ -1414,6 +1414,9 @@ static void restore_G_args(save_arg_t *sv, char **argv) | |||
1414 | * Standard says "When a subshell is entered, traps that are not being ignored | 1414 | * Standard says "When a subshell is entered, traps that are not being ignored |
1415 | * are set to the default actions". bash interprets it so that traps which | 1415 | * are set to the default actions". bash interprets it so that traps which |
1416 | * are set to '' (ignore) are NOT reset to defaults. We do the same. | 1416 | * are set to '' (ignore) are NOT reset to defaults. We do the same. |
1417 | * | ||
1418 | * TODO: don't use signal() to install sighandlers: need to mask ALL signals | ||
1419 | * while handler runs. I saw signal nesting in one strace, race window isn't small. | ||
1417 | */ | 1420 | */ |
1418 | enum { | 1421 | enum { |
1419 | SPECIAL_INTERACTIVE_SIGS = 0 | 1422 | SPECIAL_INTERACTIVE_SIGS = 0 |
@@ -1486,12 +1489,13 @@ static sighandler_t pick_sighandler(unsigned sig) | |||
1486 | unsigned sigmask = (1 << sig); | 1489 | unsigned sigmask = (1 << sig); |
1487 | 1490 | ||
1488 | #if ENABLE_HUSH_JOB | 1491 | #if ENABLE_HUSH_JOB |
1489 | /* sig is fatal? */ | 1492 | /* is sig fatal? */ |
1490 | if (G_fatal_sig_mask & sigmask) | 1493 | if (G_fatal_sig_mask & sigmask) |
1491 | handler = sigexit; | 1494 | handler = sigexit; |
1495 | else | ||
1492 | #endif | 1496 | #endif |
1493 | /* sig has special handling? */ | 1497 | /* sig has special handling? */ |
1494 | else if (G.special_sig_mask & sigmask) { | 1498 | if (G.special_sig_mask & sigmask) { |
1495 | handler = record_pending_signo; | 1499 | handler = record_pending_signo; |
1496 | /* TTIN/TTOU/TSTP can't be set to record_pending_signo | 1500 | /* TTIN/TTOU/TSTP can't be set to record_pending_signo |
1497 | * in order to ignore them: they will be raised | 1501 | * in order to ignore them: they will be raised |
@@ -5604,9 +5608,6 @@ static void re_execute_shell(char ***to_free, const char *s, | |||
5604 | * _inside_ group (just before echo 1), it works. | 5608 | * _inside_ group (just before echo 1), it works. |
5605 | * | 5609 | * |
5606 | * I conclude it means we don't need to pass active traps here. | 5610 | * I conclude it means we don't need to pass active traps here. |
5607 | * Even if we would use signal handlers instead of signal masking | ||
5608 | * in order to implement trap handling, | ||
5609 | * exec syscall below resets signals to SIG_DFL for us. | ||
5610 | */ | 5611 | */ |
5611 | *pp++ = (char *) "-c"; | 5612 | *pp++ = (char *) "-c"; |
5612 | *pp++ = (char *) s; | 5613 | *pp++ = (char *) s; |
@@ -5623,7 +5624,9 @@ static void re_execute_shell(char ***to_free, const char *s, | |||
5623 | 5624 | ||
5624 | do_exec: | 5625 | do_exec: |
5625 | debug_printf_exec("re_execute_shell pid:%d cmd:'%s'\n", getpid(), s); | 5626 | debug_printf_exec("re_execute_shell pid:%d cmd:'%s'\n", getpid(), s); |
5626 | switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS); | 5627 | /* Don't propagate SIG_IGN to the child */ |
5628 | if (SPECIAL_JOBSTOP_SIGS != 0) | ||
5629 | switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS); | ||
5627 | execve(bb_busybox_exec_path, argv, pp); | 5630 | execve(bb_busybox_exec_path, argv, pp); |
5628 | /* Fallback. Useful for init=/bin/hush usage etc */ | 5631 | /* Fallback. Useful for init=/bin/hush usage etc */ |
5629 | if (argv[0][0] == '/') | 5632 | if (argv[0][0] == '/') |
@@ -6277,7 +6280,9 @@ static void execvp_or_die(char **argv) NORETURN; | |||
6277 | static void execvp_or_die(char **argv) | 6280 | static void execvp_or_die(char **argv) |
6278 | { | 6281 | { |
6279 | debug_printf_exec("execing '%s'\n", argv[0]); | 6282 | debug_printf_exec("execing '%s'\n", argv[0]); |
6280 | switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS); | 6283 | /* Don't propagate SIG_IGN to the child */ |
6284 | if (SPECIAL_JOBSTOP_SIGS != 0) | ||
6285 | switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS); | ||
6281 | execvp(argv[0], argv); | 6286 | execvp(argv[0], argv); |
6282 | bb_perror_msg("can't execute '%s'", argv[0]); | 6287 | bb_perror_msg("can't execute '%s'", argv[0]); |
6283 | _exit(127); /* bash compat */ | 6288 | _exit(127); /* bash compat */ |
@@ -6409,7 +6414,9 @@ static NOINLINE void pseudo_exec_argv(nommu_save_t *nommu_save, | |||
6409 | # endif | 6414 | # endif |
6410 | /* Re-exec ourselves */ | 6415 | /* Re-exec ourselves */ |
6411 | debug_printf_exec("re-execing applet '%s'\n", argv[0]); | 6416 | debug_printf_exec("re-execing applet '%s'\n", argv[0]); |
6412 | switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS); | 6417 | /* Don't propagate SIG_IGN to the child */ |
6418 | if (SPECIAL_JOBSTOP_SIGS != 0) | ||
6419 | switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS); | ||
6413 | execv(bb_busybox_exec_path, argv); | 6420 | execv(bb_busybox_exec_path, argv); |
6414 | /* If they called chroot or otherwise made the binary no longer | 6421 | /* If they called chroot or otherwise made the binary no longer |
6415 | * executable, fall through */ | 6422 | * executable, fall through */ |