aboutsummaryrefslogtreecommitdiff
path: root/shell/hush.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-05-12 23:06:20 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2011-05-12 23:06:20 +0200
commit0806e401d6747c391fa0427e0ccba9951f9a1c3d (patch)
treeb64a92ccbe311f699462c48fd2737e3539450238 /shell/hush.c
parentb1ab283f0b6acc6610d64ec33a50c7b16e517797 (diff)
downloadbusybox-w32-0806e401d6747c391fa0427e0ccba9951f9a1c3d.tar.gz
busybox-w32-0806e401d6747c391fa0427e0ccba9951f9a1c3d.tar.bz2
busybox-w32-0806e401d6747c391fa0427e0ccba9951f9a1c3d.zip
hush: install signal handlers with filled sigmask
function old new delta install_sighandler - 39 +39 hush_main 1001 1031 +30 builtin_trap 386 392 +6 install_sighandlers 121 123 +2 switch_off_special_sigs 87 86 -1 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 3/1 up/down: 77/-1) Total: 76 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to '')
-rw-r--r--shell/hush.c37
1 files changed, 28 insertions, 9 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 132b974f0..4c348ec2b 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -815,6 +815,7 @@ struct globals {
815 unsigned long memleak_value; 815 unsigned long memleak_value;
816 int debug_indent; 816 int debug_indent;
817#endif 817#endif
818 struct sigaction sa;
818 char user_input_buf[ENABLE_FEATURE_EDITING ? CONFIG_FEATURE_EDITING_MAX_LEN : 2]; 819 char user_input_buf[ENABLE_FEATURE_EDITING ? CONFIG_FEATURE_EDITING_MAX_LEN : 2];
819}; 820};
820#define G (*ptr_to_globals) 821#define G (*ptr_to_globals)
@@ -823,6 +824,9 @@ struct globals {
823 * is global, thus "G." prefix is a useful hint */ 824 * is global, thus "G." prefix is a useful hint */
824#define INIT_G() do { \ 825#define INIT_G() do { \
825 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 826 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
827 /* memset(&G.sa, 0, sizeof(G.sa)); */ \
828 sigfillset(&G.sa.sa_mask); \
829 G.sa.sa_flags = SA_RESTART; \
826} while (0) 830} while (0)
827 831
828 832
@@ -1414,9 +1418,6 @@ 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 1418 * 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 1419 * 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. 1420 * 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.
1420 */ 1421 */
1421enum { 1422enum {
1422 SPECIAL_INTERACTIVE_SIGS = 0 1423 SPECIAL_INTERACTIVE_SIGS = 0
@@ -1444,6 +1445,24 @@ static void record_pending_signo(int sig)
1444#endif 1445#endif
1445} 1446}
1446 1447
1448static sighandler_t install_sighandler(int sig, sighandler_t handler)
1449{
1450 struct sigaction old_sa;
1451
1452 /* We could use signal() to install handlers... almost:
1453 * except that we need to mask ALL signals while handlers run.
1454 * I saw signal nesting in strace, race window isn't small.
1455 * SA_RESTART is also needed, but in Linux, signal()
1456 * sets SA_RESTART too.
1457 */
1458 /* memset(&G.sa, 0, sizeof(G.sa)); - already done */
1459 /* sigfillset(&G.sa.sa_mask); - already done */
1460 /* G.sa.sa_flags = SA_RESTART; - already done */
1461 G.sa.sa_handler = handler;
1462 sigaction(sig, &G.sa, &old_sa);
1463 return old_sa.sa_handler;
1464}
1465
1447#if ENABLE_HUSH_JOB 1466#if ENABLE_HUSH_JOB
1448 1467
1449/* After [v]fork, in child: do not restore tty pgrp on xfunc death */ 1468/* After [v]fork, in child: do not restore tty pgrp on xfunc death */
@@ -5451,7 +5470,7 @@ static void switch_off_special_sigs(unsigned mask)
5451 G.traps[sig] = NULL; 5470 G.traps[sig] = NULL;
5452 } 5471 }
5453 /* We are here only if no trap or trap was not '' */ 5472 /* We are here only if no trap or trap was not '' */
5454 signal(sig, SIG_DFL); 5473 install_sighandler(sig, SIG_DFL);
5455 } 5474 }
5456} 5475}
5457 5476
@@ -5496,7 +5515,7 @@ static void reset_traps_to_defaults(void)
5496 /* There is no signal for trap 0 (EXIT) */ 5515 /* There is no signal for trap 0 (EXIT) */
5497 if (sig == 0) 5516 if (sig == 0)
5498 continue; 5517 continue;
5499 signal(sig, pick_sighandler(sig)); 5518 install_sighandler(sig, pick_sighandler(sig));
5500 } 5519 }
5501} 5520}
5502 5521
@@ -7524,7 +7543,7 @@ static void install_sighandlers(unsigned mask)
7524 sig++; 7543 sig++;
7525 if (!(mask & 1)) 7544 if (!(mask & 1))
7526 continue; 7545 continue;
7527 old_handler = signal(sig, pick_sighandler(sig)); 7546 old_handler = install_sighandler(sig, pick_sighandler(sig));
7528 /* POSIX allows shell to re-enable SIGCHLD 7547 /* POSIX allows shell to re-enable SIGCHLD
7529 * even if it was SIG_IGN on entry. 7548 * even if it was SIG_IGN on entry.
7530 * Therefore we skip IGN check for it: 7549 * Therefore we skip IGN check for it:
@@ -7533,7 +7552,7 @@ static void install_sighandlers(unsigned mask)
7533 continue; 7552 continue;
7534 if (old_handler == SIG_IGN) { 7553 if (old_handler == SIG_IGN) {
7535 /* oops... restore back to IGN, and record this fact */ 7554 /* oops... restore back to IGN, and record this fact */
7536 signal(sig, old_handler); 7555 install_sighandler(sig, old_handler);
7537 if (!G.traps) 7556 if (!G.traps)
7538 G.traps = xzalloc(sizeof(G.traps[0]) * NSIG); 7557 G.traps = xzalloc(sizeof(G.traps[0]) * NSIG);
7539 free(G.traps[sig]); 7558 free(G.traps[sig]);
@@ -7854,7 +7873,7 @@ int hush_main(int argc, char **argv)
7854 for (sig = 1; sig < NSIG; sig++) { 7873 for (sig = 1; sig < NSIG; sig++) {
7855 if (empty_trap_mask & (1LL << sig)) { 7874 if (empty_trap_mask & (1LL << sig)) {
7856 G.traps[sig] = xzalloc(1); /* == xstrdup(""); */ 7875 G.traps[sig] = xzalloc(1); /* == xstrdup(""); */
7857 signal(sig, SIG_IGN); 7876 install_sighandler(sig, SIG_IGN);
7858 } 7877 }
7859 } 7878 }
7860 } 7879 }
@@ -8389,7 +8408,7 @@ static int FAST_FUNC builtin_trap(char **argv)
8389 else 8408 else
8390 /* We are removing trap handler */ 8409 /* We are removing trap handler */
8391 handler = pick_sighandler(sig); 8410 handler = pick_sighandler(sig);
8392 signal(sig, handler); 8411 install_sighandler(sig, handler);
8393 } 8412 }
8394 return ret; 8413 return ret;
8395 } 8414 }