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 /shell | |
| 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>
Diffstat (limited to 'shell')
| -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 */ |
