aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-05-12 13:12:47 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2011-05-12 13:12:47 +0200
commit75e77deab11dc976d55197fcd6021030ed323e07 (patch)
tree866bab5b43960e74bae3e7ab423a54801bc745d3
parentebc1ee2e2a243a0ff3de6d2b70406ba75b771fa0 (diff)
downloadbusybox-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.c27
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 */
1418enum { 1421enum {
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;
6277static void execvp_or_die(char **argv) 6280static 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 */