aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-02-16 22:58:56 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-02-16 22:58:56 +0000
commit25591c322c9305bd54d3ab80cfaf01ef87640d77 (patch)
tree66ce77758e35f4faa2d5f611d0535365f2cba00a
parent7fc294cdfe1e7f4a12c44f984a698b0c0f609075 (diff)
downloadbusybox-w32-25591c322c9305bd54d3ab80cfaf01ef87640d77.tar.gz
busybox-w32-25591c322c9305bd54d3ab80cfaf01ef87640d77.tar.bz2
busybox-w32-25591c322c9305bd54d3ab80cfaf01ef87640d77.zip
libbb: introduce bb_signals and bb_signals_recursive,
which sets same handler for many signals. sig_catch is nuked (bb_signals_recursive is more descriptive name). *: use them as appropriate. function old new delta bb_signals_recursive - 95 +95 bb_signals - 52 +52 run_command 258 273 +15 svlogd_main 1368 1377 +9 runsv_main 1746 1752 +6 runsvdir_main 1643 1646 +3 UNSPEC_print 64 66 +2 time_main 1128 1127 -1 ... resize_main 246 210 -36 sig_catch 63 - -63 set_fatal_sighandler 85 14 -71 ------------------------------------------------------------------------------ (add/remove: 2/1 grow/shrink: 5/24 up/down: 182/-548) Total: -366 bytes
-rw-r--r--console-tools/resize.c10
-rw-r--r--coreutils/tee.c4
-rw-r--r--include/libbb.h20
-rw-r--r--init/init.c48
-rw-r--r--libbb/Kbuild1
-rw-r--r--libbb/signals.c80
-rw-r--r--libbb/xfuncs.c42
-rw-r--r--loginutils/passwd.c8
-rw-r--r--miscutils/less.c6
-rw-r--r--miscutils/microcom.c10
-rw-r--r--miscutils/time.c16
-rw-r--r--miscutils/watchdog.c6
-rw-r--r--networking/dnsd.c10
-rw-r--r--networking/nc_bloaty.c14
-rw-r--r--networking/sendmail.c6
-rw-r--r--networking/slattach.c10
-rw-r--r--networking/telnetd.c3
-rw-r--r--networking/udhcp/signalpipe.c8
-rw-r--r--procps/top.c6
-rw-r--r--runit/runsv.c10
-rw-r--r--runit/runsvdir.c10
-rw-r--r--runit/svlogd.c16
-rw-r--r--shell/hush.c36
-rw-r--r--sysklogd/klogd.c7
-rw-r--r--sysklogd/syslogd.c8
-rw-r--r--util-linux/more.c8
26 files changed, 249 insertions, 154 deletions
diff --git a/console-tools/resize.c b/console-tools/resize.c
index b4cdf50d0..7f72b9a46 100644
--- a/console-tools/resize.c
+++ b/console-tools/resize.c
@@ -37,10 +37,12 @@ int resize_main(int argc, char **argv)
37 new = old_termios; 37 new = old_termios;
38 new.c_cflag |= (CLOCAL | CREAD); 38 new.c_cflag |= (CLOCAL | CREAD);
39 new.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); 39 new.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
40 signal(SIGINT, onintr); 40 bb_signals(0
41 signal(SIGQUIT, onintr); 41 + (1 << SIGINT)
42 signal(SIGTERM, onintr); 42 + (1 << SIGQUIT)
43 signal(SIGALRM, onintr); 43 + (1 << SIGTERM)
44 + (1 << SIGALRM)
45 , onintr);
44 tcsetattr(STDERR_FILENO, TCSANOW, &new); 46 tcsetattr(STDERR_FILENO, TCSANOW, &new);
45 47
46 /* save_cursor_pos 7 48 /* save_cursor_pos 7
diff --git a/coreutils/tee.c b/coreutils/tee.c
index 13fb4a3c1..b38801755 100644
--- a/coreutils/tee.c
+++ b/coreutils/tee.c
@@ -36,12 +36,12 @@ int tee_main(int argc, char **argv)
36 mode += (retval & 2); /* Since 'a' is the 2nd option... */ 36 mode += (retval & 2); /* Since 'a' is the 2nd option... */
37 37
38 if (retval & 1) { 38 if (retval & 1) {
39 signal(SIGINT, SIG_IGN); /* TODO - switch to sigaction. */ 39 signal(SIGINT, SIG_IGN); /* TODO - switch to sigaction. (why?) */
40 } 40 }
41 retval = EXIT_SUCCESS; 41 retval = EXIT_SUCCESS;
42 /* gnu tee ignores SIGPIPE in case one of the output files is a pipe 42 /* gnu tee ignores SIGPIPE in case one of the output files is a pipe
43 * that doesn't consume all its input. Good idea... */ 43 * that doesn't consume all its input. Good idea... */
44 signal(SIGPIPE, SIG_IGN); /* TODO - switch to sigaction. */ 44 signal(SIGPIPE, SIG_IGN);
45 45
46 /* Allocate an array of FILE *'s, with one extra for a sentinal. */ 46 /* Allocate an array of FILE *'s, with one extra for a sentinal. */
47 fp = files = xzalloc(sizeof(FILE *) * (argc + 2)); 47 fp = files = xzalloc(sizeof(FILE *) * (argc + 2));
diff --git a/include/libbb.h b/include/libbb.h
index f505cc718..67afcdf94 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -274,14 +274,18 @@ char *xrealloc_getcwd_or_warn(char *cwd);
274 274
275char *xmalloc_follow_symlinks(const char *path); 275char *xmalloc_follow_symlinks(const char *path);
276 276
277//TODO: signal(sid, f) is the same? then why? 277//enum {
278extern void sig_catch(int,void (*)(int)); 278// BB_SIGS_FATAL = ,
279//#define sig_ignore(s) (sig_catch((s), SIG_IGN)) 279//};
280//#define sig_uncatch(s) (sig_catch((s), SIG_DFL)) 280void bb_signals(int sigs, void (*f)(int));
281extern void sig_block(int); 281/* Unlike signal() and bb_signals, sets handler with sigaction()
282extern void sig_unblock(int); 282 * and in a way that while signal handler is run, no other signals
283/* UNUSED: extern void sig_blocknone(void); */ 283 * will be blocked: */
284extern void sig_pause(void); 284void bb_signals_recursive(int sigs, void (*f)(int));
285void sig_block(int);
286void sig_unblock(int);
287/* UNUSED: void sig_blocknone(void); */
288void sig_pause(void);
285 289
286 290
287void xsetgid(gid_t gid); 291void xsetgid(gid_t gid);
diff --git a/init/init.c b/init/init.c
index 9e24817b7..080c5b3af 100644
--- a/init/init.c
+++ b/init/init.c
@@ -319,15 +319,17 @@ static pid_t run(const struct init_action *a)
319 /* Child */ 319 /* Child */
320 320
321 /* Reset signal handlers that were set by the parent process */ 321 /* Reset signal handlers that were set by the parent process */
322 signal(SIGUSR1, SIG_DFL); 322 bb_signals(0
323 signal(SIGUSR2, SIG_DFL); 323 + (1 << SIGUSR1)
324 signal(SIGINT, SIG_DFL); 324 + (1 << SIGUSR2)
325 signal(SIGTERM, SIG_DFL); 325 + (1 << SIGINT)
326 signal(SIGHUP, SIG_DFL); 326 + (1 << SIGTERM)
327 signal(SIGQUIT, SIG_DFL); 327 + (1 << SIGHUP)
328 signal(SIGCONT, SIG_DFL); 328 + (1 << SIGQUIT)
329 signal(SIGSTOP, SIG_DFL); 329 + (1 << SIGCONT)
330 signal(SIGTSTP, SIG_DFL); 330 + (1 << SIGSTOP)
331 + (1 << SIGTSTP)
332 , SIG_DFL);
331 333
332 /* Create a new session and make ourself the process 334 /* Create a new session and make ourself the process
333 * group leader */ 335 * group leader */
@@ -349,9 +351,11 @@ static pid_t run(const struct init_action *a)
349 351
350 if (pid > 0) { 352 if (pid > 0) {
351 /* Parent - wait till the child is done */ 353 /* Parent - wait till the child is done */
352 signal(SIGINT, SIG_IGN); 354 bb_signals(0
353 signal(SIGTSTP, SIG_IGN); 355 + (1 << SIGINT)
354 signal(SIGQUIT, SIG_IGN); 356 + (1 << SIGTSTP)
357 + (1 << SIGQUIT)
358 , SIG_IGN);
355 signal(SIGCHLD, SIG_DFL); 359 signal(SIGCHLD, SIG_DFL);
356 360
357 waitfor(pid); 361 waitfor(pid);
@@ -864,15 +868,21 @@ int init_main(int argc, char **argv)
864 } 868 }
865 /* Set up sig handlers -- be sure to 869 /* Set up sig handlers -- be sure to
866 * clear all of these in run() */ 870 * clear all of these in run() */
867 signal(SIGHUP, exec_restart_action); 871 bb_signals(0
868 signal(SIGQUIT, exec_restart_action); 872 + (1 << SIGHUP)
869 signal(SIGUSR1, halt_reboot_pwoff); /* halt */ 873 + (1 << SIGQUIT)
870 signal(SIGUSR2, halt_reboot_pwoff); /* poweroff */ 874 , exec_restart_action);
871 signal(SIGTERM, halt_reboot_pwoff); /* reboot */ 875 bb_signals(0
876 + (1 << SIGUSR1) /* halt */
877 + (1 << SIGUSR2) /* poweroff */
878 + (1 << SIGTERM) /* reboot */
879 , halt_reboot_pwoff);
872 signal(SIGINT, ctrlaltdel_signal); 880 signal(SIGINT, ctrlaltdel_signal);
873 signal(SIGCONT, cont_handler); 881 signal(SIGCONT, cont_handler);
874 signal(SIGSTOP, stop_handler); 882 bb_signals(0
875 signal(SIGTSTP, stop_handler); 883 + (1 << SIGSTOP)
884 + (1 << SIGTSTP)
885 , stop_handler);
876 886
877 /* Turn off rebooting via CTL-ALT-DEL -- we get a 887 /* Turn off rebooting via CTL-ALT-DEL -- we get a
878 * SIGINT on CAD so we can shut things down gracefully... */ 888 * SIGINT on CAD so we can shut things down gracefully... */
diff --git a/libbb/Kbuild b/libbb/Kbuild
index 2fb1b2420..515368de7 100644
--- a/libbb/Kbuild
+++ b/libbb/Kbuild
@@ -78,6 +78,7 @@ lib-y += safe_strncpy.o
78lib-y += safe_write.o 78lib-y += safe_write.o
79lib-y += setup_environment.o 79lib-y += setup_environment.o
80lib-y += sha1.o 80lib-y += sha1.o
81lib-y += signals.o
81lib-y += simplify_path.o 82lib-y += simplify_path.o
82lib-y += skip_whitespace.o 83lib-y += skip_whitespace.o
83lib-y += speed_table.o 84lib-y += speed_table.o
diff --git a/libbb/signals.c b/libbb/signals.c
new file mode 100644
index 000000000..f7e4908e7
--- /dev/null
+++ b/libbb/signals.c
@@ -0,0 +1,80 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Utility routines.
4 *
5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
6 * Copyright (C) 2006 Rob Landley
7 * Copyright (C) 2006 Denis Vlasenko
8 *
9 * Licensed under GPL version 2, see file LICENSE in this tarball for details.
10 */
11
12#include "libbb.h"
13
14void bb_signals(int sigs, void (*f)(int))
15{
16 int sig_no = 0;
17 int bit = 1;
18
19 while (sigs) {
20 if (sigs & bit) {
21 sigs &= ~bit;
22 signal(sig_no, f);
23 }
24 sig_no++;
25 bit <<= 1;
26 }
27}
28
29void bb_signals_recursive(int sigs, void (*f)(int))
30{
31 int sig_no = 0;
32 int bit = 1;
33 struct sigaction sa;
34
35 memset(&sa, 0, sizeof(sa));
36 sa.sa_handler = f;
37 /*sa.sa_flags = 0;*/
38 /*sigemptyset(&sa.sa_mask); - hope memset did it*/
39
40 while (sigs) {
41 if (sigs & bit) {
42 sigs &= ~bit;
43 sigaction(sig_no, &sa, NULL);
44 }
45 sig_no++;
46 bit <<= 1;
47 }
48}
49
50void sig_block(int sig)
51{
52 sigset_t ss;
53 sigemptyset(&ss);
54 sigaddset(&ss, sig);
55 sigprocmask(SIG_BLOCK, &ss, NULL);
56}
57
58void sig_unblock(int sig)
59{
60 sigset_t ss;
61 sigemptyset(&ss);
62 sigaddset(&ss, sig);
63 sigprocmask(SIG_UNBLOCK, &ss, NULL);
64}
65
66#if 0
67void sig_blocknone(void)
68{
69 sigset_t ss;
70 sigemptyset(&ss);
71 sigprocmask(SIG_SETMASK, &ss, NULL);
72}
73#endif
74
75void sig_pause(void)
76{
77 sigset_t ss;
78 sigemptyset(&ss);
79 sigsuspend(&ss);
80}
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c
index 445e07717..8dd414d6a 100644
--- a/libbb/xfuncs.c
+++ b/libbb/xfuncs.c
@@ -234,48 +234,6 @@ void xfflush_stdout(void)
234 } 234 }
235} 235}
236 236
237void sig_block(int sig)
238{
239 sigset_t ss;
240 sigemptyset(&ss);
241 sigaddset(&ss, sig);
242 sigprocmask(SIG_BLOCK, &ss, NULL);
243}
244
245void sig_unblock(int sig)
246{
247 sigset_t ss;
248 sigemptyset(&ss);
249 sigaddset(&ss, sig);
250 sigprocmask(SIG_UNBLOCK, &ss, NULL);
251}
252
253#if 0
254void sig_blocknone(void)
255{
256 sigset_t ss;
257 sigemptyset(&ss);
258 sigprocmask(SIG_SETMASK, &ss, NULL);
259}
260#endif
261
262void sig_catch(int sig, void (*f)(int))
263{
264 struct sigaction sa;
265 sa.sa_handler = f;
266 sa.sa_flags = 0;
267 sigemptyset(&sa.sa_mask);
268 sigaction(sig, &sa, NULL);
269}
270
271void sig_pause(void)
272{
273 sigset_t ss;
274 sigemptyset(&ss);
275 sigsuspend(&ss);
276}
277
278
279void xsetenv(const char *key, const char *value) 237void xsetenv(const char *key, const char *value)
280{ 238{
281 if (setenv(key, value, 1)) 239 if (setenv(key, value, 1))
diff --git a/loginutils/passwd.c b/loginutils/passwd.c
index 0df084e5a..2f85e9f21 100644
--- a/loginutils/passwd.c
+++ b/loginutils/passwd.c
@@ -171,9 +171,11 @@ int passwd_main(int argc, char **argv)
171 171
172 rlimit_fsize.rlim_cur = rlimit_fsize.rlim_max = 512L * 30000; 172 rlimit_fsize.rlim_cur = rlimit_fsize.rlim_max = 512L * 30000;
173 setrlimit(RLIMIT_FSIZE, &rlimit_fsize); 173 setrlimit(RLIMIT_FSIZE, &rlimit_fsize);
174 signal(SIGHUP, SIG_IGN); 174 bb_signals(0
175 signal(SIGINT, SIG_IGN); 175 + (1 << SIGHUP)
176 signal(SIGQUIT, SIG_IGN); 176 + (1 << SIGINT)
177 + (1 << SIGQUIT)
178 , SIG_IGN);
177 umask(077); 179 umask(077);
178 xsetuid(0); 180 xsetuid(0);
179 181
diff --git a/miscutils/less.c b/miscutils/less.c
index 5ffebcd6d..85c5ec536 100644
--- a/miscutils/less.c
+++ b/miscutils/less.c
@@ -1355,8 +1355,10 @@ int less_main(int argc, char **argv)
1355 empty_line_marker = ""; 1355 empty_line_marker = "";
1356 1356
1357 tcgetattr(kbd_fd, &term_orig); 1357 tcgetattr(kbd_fd, &term_orig);
1358 signal(SIGTERM, sig_catcher); 1358 bb_signals(0
1359 signal(SIGINT, sig_catcher); 1359 + (1 << SIGTERM)
1360 + (1 << SIGINT)
1361 , sig_catcher);
1360 term_less = term_orig; 1362 term_less = term_orig;
1361 term_less.c_lflag &= ~(ICANON | ECHO); 1363 term_less.c_lflag &= ~(ICANON | ECHO);
1362 term_less.c_iflag &= ~(IXON | ICRNL); 1364 term_less.c_iflag &= ~(IXON | ICRNL);
diff --git a/miscutils/microcom.c b/miscutils/microcom.c
index 63b07fd69..b9ed9e401 100644
--- a/miscutils/microcom.c
+++ b/miscutils/microcom.c
@@ -99,10 +99,12 @@ int microcom_main(int argc, char **argv)
99 } 99 }
100 100
101 // setup signals 101 // setup signals
102 sig_catch(SIGHUP, signal_handler); 102 bb_signals_recursive(0
103 sig_catch(SIGINT, signal_handler); 103 + (1 << SIGHUP)
104 sig_catch(SIGTERM, signal_handler); 104 + (1 << SIGINT)
105 sig_catch(SIGPIPE, signal_handler); 105 + (1 << SIGTERM)
106 + (1 << SIGPIPE)
107 , signal_handler);
106 108
107 // error exit code if we fail to open the device 109 // error exit code if we fail to open the device
108 signalled = 1; 110 signalled = 1;
diff --git a/miscutils/time.c b/miscutils/time.c
index d21944e01..677ca6d8b 100644
--- a/miscutils/time.c
+++ b/miscutils/time.c
@@ -61,7 +61,7 @@ static const char long_format[] ALIGN1 =
61 Return 0 on error, 1 if ok. */ 61 Return 0 on error, 1 if ok. */
62 62
63/* pid_t is short on BSDI, so don't try to promote it. */ 63/* pid_t is short on BSDI, so don't try to promote it. */
64static int resuse_end(pid_t pid, resource_t * resp) 64static int resuse_end(pid_t pid, resource_t *resp)
65{ 65{
66 int status; 66 int status;
67 pid_t caught; 67 pid_t caught;
@@ -69,7 +69,7 @@ static int resuse_end(pid_t pid, resource_t * resp)
69 /* Ignore signals, but don't ignore the children. When wait3 69 /* Ignore signals, but don't ignore the children. When wait3
70 returns the child process, set the time the command finished. */ 70 returns the child process, set the time the command finished. */
71 while ((caught = wait3(&status, 0, &resp->ru)) != pid) { 71 while ((caught = wait3(&status, 0, &resp->ru)) != pid) {
72 if (caught == -1) 72 if (caught == -1 && errno != EINTR)
73 return 0; 73 return 0;
74 } 74 }
75 resp->elapsed_ms = (monotonic_us() / 1000) - resp->elapsed_ms; 75 resp->elapsed_ms = (monotonic_us() / 1000) - resp->elapsed_ms;
@@ -373,24 +373,26 @@ static void summarize(const char *fmt, char **command, resource_t * resp)
373 373
374/* Run command CMD and return statistics on it. 374/* Run command CMD and return statistics on it.
375 Put the statistics in *RESP. */ 375 Put the statistics in *RESP. */
376static void run_command(char *const *cmd, resource_t * resp) 376static void run_command(char *const *cmd, resource_t *resp)
377{ 377{
378 pid_t pid; /* Pid of child. */ 378 pid_t pid; /* Pid of child. */
379 __sighandler_t interrupt_signal, quit_signal; 379 void (*interrupt_signal)(int);
380 void (*quit_signal)(int);
380 381
381 resp->elapsed_ms = monotonic_us() / 1000; 382 resp->elapsed_ms = monotonic_us() / 1000;
382 pid = vfork(); /* Run CMD as child process. */ 383 pid = vfork(); /* Run CMD as child process. */
383 if (pid < 0) 384 if (pid < 0)
384 bb_error_msg_and_die("cannot fork"); 385 bb_error_msg_and_die("cannot fork");
385 else if (pid == 0) { /* If child. */ 386 if (pid == 0) { /* If child. */
386 /* Don't cast execvp arguments; that causes errors on some systems, 387 /* Don't cast execvp arguments; that causes errors on some systems,
387 versus merely warnings if the cast is left off. */ 388 versus merely warnings if the cast is left off. */
388 BB_EXECVP(cmd[0], cmd); 389 BB_EXECVP(cmd[0], cmd);
389 bb_error_msg("cannot run %s", cmd[0]); 390 xfunc_error_retval = (errno == ENOENT ? 127 : 126);
390 _exit(errno == ENOENT ? 127 : 126); 391 bb_error_msg_and_die("cannot run %s", cmd[0]);
391 } 392 }
392 393
393 /* Have signals kill the child but not self (if possible). */ 394 /* Have signals kill the child but not self (if possible). */
395//TODO: just block all sigs? and reenable them in the very end in main?
394 interrupt_signal = signal(SIGINT, SIG_IGN); 396 interrupt_signal = signal(SIGINT, SIG_IGN);
395 quit_signal = signal(SIGQUIT, SIG_IGN); 397 quit_signal = signal(SIGQUIT, SIG_IGN);
396 398
diff --git a/miscutils/watchdog.c b/miscutils/watchdog.c
index e040c64fd..28bd35813 100644
--- a/miscutils/watchdog.c
+++ b/miscutils/watchdog.c
@@ -47,8 +47,10 @@ int watchdog_main(int argc, char **argv)
47 bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv); 47 bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv);
48 } 48 }
49 49
50 signal(SIGHUP, watchdog_shutdown); 50 bb_signals(0
51 signal(SIGINT, watchdog_shutdown); 51 + (1 << SIGHUP)
52 + (1 << SIGINT)
53 , watchdog_shutdown);
52 54
53 /* Use known fd # - avoid needing global 'int fd' */ 55 /* Use known fd # - avoid needing global 'int fd' */
54 xmove_fd(xopen(argv[argc - 1], O_WRONLY), 3); 56 xmove_fd(xopen(argv[argc - 1], O_WRONLY), 3);
diff --git a/networking/dnsd.c b/networking/dnsd.c
index 5e7886167..0a5278377 100644
--- a/networking/dnsd.c
+++ b/networking/dnsd.c
@@ -361,14 +361,16 @@ int dnsd_main(int argc, char **argv)
361 dnsentryinit(); 361 dnsentryinit();
362 362
363 signal(SIGINT, interrupt); 363 signal(SIGINT, interrupt);
364 /* why? signal(SIGPIPE, SIG_IGN); */ 364 bb_signals(0
365 signal(SIGHUP, SIG_IGN); 365 /* why? + (1 << SIGPIPE) */
366 + (1 << SIGHUP)
366#ifdef SIGTSTP 367#ifdef SIGTSTP
367 signal(SIGTSTP, SIG_IGN); 368 + (1 << SIGTSTP)
368#endif 369#endif
369#ifdef SIGURG 370#ifdef SIGURG
370 signal(SIGURG, SIG_IGN); 371 + (1 << SIGURG)
371#endif 372#endif
373 , SIG_IGN);
372 374
373 lsa = xdotted2sockaddr(listen_interface, port); 375 lsa = xdotted2sockaddr(listen_interface, port);
374 udps = xsocket(lsa->u.sa.sa_family, SOCK_DGRAM, 0); 376 udps = xsocket(lsa->u.sa.sa_family, SOCK_DGRAM, 0);
diff --git a/networking/nc_bloaty.c b/networking/nc_bloaty.c
index 206c5e5d9..853577aef 100644
--- a/networking/nc_bloaty.c
+++ b/networking/nc_bloaty.c
@@ -683,14 +683,18 @@ int nc_main(int argc, char **argv)
683 PTR_TO_GLOBALS = xzalloc(sizeof(G)); 683 PTR_TO_GLOBALS = xzalloc(sizeof(G));
684 684
685 /* catch a signal or two for cleanup */ 685 /* catch a signal or two for cleanup */
686 signal(SIGINT, catch); 686 bb_signals(0
687 signal(SIGQUIT, catch); 687 + (1 << SIGINT)
688 signal(SIGTERM, catch); 688 + (1 << SIGQUIT)
689 + (1 << SIGTERM)
690 , catch);
689 /* and suppress others... */ 691 /* and suppress others... */
692 bb_signals(0
690#ifdef SIGURG 693#ifdef SIGURG
691 signal(SIGURG, SIG_IGN); 694 + (1 << SIGURG)
692#endif 695#endif
693 signal(SIGPIPE, SIG_IGN); /* important! */ 696 + (1 << SIGPIPE) /* important! */
697 , SIG_IGN);
694 698
695 proggie = argv; 699 proggie = argv;
696 while (*++proggie) { 700 while (*++proggie) {
diff --git a/networking/sendmail.c b/networking/sendmail.c
index 63305d149..fa995abf4 100644
--- a/networking/sendmail.c
+++ b/networking/sendmail.c
@@ -111,8 +111,10 @@ static void launch_helper(const char **argv)
111 _exit(127); 111 _exit(127);
112 } 112 }
113 // parent - check whether child is alive 113 // parent - check whether child is alive
114 sig_catch(SIGCHLD, signal_handler); 114 bb_signals_recursive(0
115 sig_catch(SIGALRM, signal_handler); 115 + (1 << SIGCHLD)
116 + (1 << SIGALRM)
117 , signal_handler);
116 signal_handler(SIGCHLD); 118 signal_handler(SIGCHLD);
117 // child seems OK -> parent goes on 119 // child seems OK -> parent goes on
118} 120}
diff --git a/networking/slattach.c b/networking/slattach.c
index 17df4fa9e..e501d82e1 100644
--- a/networking/slattach.c
+++ b/networking/slattach.c
@@ -175,10 +175,12 @@ int slattach_main(int argc, char **argv)
175 175
176 /* Trap signals in order to restore tty states upon exit */ 176 /* Trap signals in order to restore tty states upon exit */
177 if (!(opt & OPT_e_quit)) { 177 if (!(opt & OPT_e_quit)) {
178 signal(SIGHUP, sig_handler); 178 bb_signals(0
179 signal(SIGINT, sig_handler); 179 + (1 << SIGHUP)
180 signal(SIGQUIT, sig_handler); 180 + (1 << SIGINT)
181 signal(SIGTERM, sig_handler); 181 + (1 << SIGQUIT)
182 + (1 << SIGTERM)
183 , sig_handler);
182 } 184 }
183 185
184 /* Open tty */ 186 /* Open tty */
diff --git a/networking/telnetd.c b/networking/telnetd.c
index 962e5cc7b..0bffa9700 100644
--- a/networking/telnetd.c
+++ b/networking/telnetd.c
@@ -279,8 +279,7 @@ make_new_session(
279 setsid(); 279 setsid();
280 280
281 /* Restore default signal handling */ 281 /* Restore default signal handling */
282 signal(SIGCHLD, SIG_DFL); 282 bb_signals((1 << SIGCHLD) + (1 << SIGPIPE), SIG_DFL);
283 signal(SIGPIPE, SIG_DFL);
284 283
285 /* open the child's side of the tty. */ 284 /* open the child's side of the tty. */
286 /* NB: setsid() disconnects from any previous ctty's. Therefore 285 /* NB: setsid() disconnects from any previous ctty's. Therefore
diff --git a/networking/udhcp/signalpipe.c b/networking/udhcp/signalpipe.c
index 918abd02d..1486b3b2d 100644
--- a/networking/udhcp/signalpipe.c
+++ b/networking/udhcp/signalpipe.c
@@ -42,9 +42,11 @@ void udhcp_sp_setup(void)
42 close_on_exec_on(signal_pipe.rd); 42 close_on_exec_on(signal_pipe.rd);
43 close_on_exec_on(signal_pipe.wr); 43 close_on_exec_on(signal_pipe.wr);
44 ndelay_on(signal_pipe.wr); 44 ndelay_on(signal_pipe.wr);
45 signal(SIGUSR1, signal_handler); 45 bb_signals(0
46 signal(SIGUSR2, signal_handler); 46 + (1 << SIGUSR1)
47 signal(SIGTERM, signal_handler); 47 + (1 << SIGUSR2)
48 + (1 << SIGTERM)
49 , signal_handler);
48} 50}
49 51
50 52
diff --git a/procps/top.c b/procps/top.c
index a47150ea7..f4bb5094a 100644
--- a/procps/top.c
+++ b/procps/top.c
@@ -772,8 +772,10 @@ int top_main(int argc, char **argv)
772 /* unbuffered input, turn off echo */ 772 /* unbuffered input, turn off echo */
773 new_settings.c_lflag &= ~(ISIG | ICANON | ECHO | ECHONL); 773 new_settings.c_lflag &= ~(ISIG | ICANON | ECHO | ECHONL);
774 774
775 signal(SIGTERM, sig_catcher); 775 bb_signals(0
776 signal(SIGINT, sig_catcher); 776 + (1 << SIGTERM)
777 + (1 << SIGINT)
778 , sig_catcher);
777 tcsetattr(0, TCSANOW, (void *) &new_settings); 779 tcsetattr(0, TCSANOW, (void *) &new_settings);
778 atexit(reset_term); 780 atexit(reset_term);
779#endif /* FEATURE_USE_TERMIOS */ 781#endif /* FEATURE_USE_TERMIOS */
diff --git a/runit/runsv.c b/runit/runsv.c
index e1d99e2df..02271d68b 100644
--- a/runit/runsv.c
+++ b/runit/runsv.c
@@ -345,8 +345,10 @@ static void startservice(struct svdir *s)
345 xdup2(logpipe.wr, 1); 345 xdup2(logpipe.wr, 1);
346 } 346 }
347 } 347 }
348 signal(SIGCHLD, SIG_DFL); 348 bb_signals(0
349 signal(SIGTERM, SIG_DFL); 349 + (1 << SIGCHLD)
350 + (1 << SIGTERM)
351 , SIG_DFL);
350 sig_unblock(SIGCHLD); 352 sig_unblock(SIGCHLD);
351 sig_unblock(SIGTERM); 353 sig_unblock(SIGTERM);
352 execvp(*run, run); 354 execvp(*run, run);
@@ -460,9 +462,9 @@ int runsv_main(int argc, char **argv)
460 ndelay_on(selfpipe.wr); 462 ndelay_on(selfpipe.wr);
461 463
462 sig_block(SIGCHLD); 464 sig_block(SIGCHLD);
463 sig_catch(SIGCHLD, s_child); 465 bb_signals_recursive(1 << SIGCHLD, s_child);
464 sig_block(SIGTERM); 466 sig_block(SIGTERM);
465 sig_catch(SIGTERM, s_term); 467 bb_signals_recursive(1 << SIGTERM, s_term);
466 468
467 xchdir(dir); 469 xchdir(dir);
468 /* bss: svd[0].pid = 0; */ 470 /* bss: svd[0].pid = 0; */
diff --git a/runit/runsvdir.c b/runit/runsvdir.c
index 4225ac101..3ff1d4c23 100644
--- a/runit/runsvdir.c
+++ b/runit/runsvdir.c
@@ -100,8 +100,10 @@ static void runsv(int no, const char *name)
100 /* child */ 100 /* child */
101 if (set_pgrp) 101 if (set_pgrp)
102 setsid(); 102 setsid();
103 signal(SIGHUP, SIG_DFL); 103 bb_signals(0
104 signal(SIGTERM, SIG_DFL); 104 + (1 << SIGHUP)
105 + (1 << SIGTERM)
106 , SIG_DFL);
105 execvp(prog[0], prog); 107 execvp(prog[0], prog);
106 fatal2_cannot("start runsv ", name); 108 fatal2_cannot("start runsv ", name);
107 } 109 }
@@ -232,8 +234,8 @@ int runsvdir_main(int argc, char **argv)
232 bb_show_usage(); 234 bb_show_usage();
233 } 235 }
234 236
235 sig_catch(SIGTERM, s_term); 237 bb_signals_recursive(1 << SIGTERM, s_term);
236 sig_catch(SIGHUP, s_hangup); 238 bb_signals_recursive(1 << SIGHUP, s_hangup);
237 svdir = *argv++; 239 svdir = *argv++;
238 if (argv && *argv) { 240 if (argv && *argv) {
239 rplog = *argv; 241 rplog = *argv;
diff --git a/runit/svlogd.c b/runit/svlogd.c
index 9c169da1f..73570dad0 100644
--- a/runit/svlogd.c
+++ b/runit/svlogd.c
@@ -222,9 +222,11 @@ static unsigned processorstart(struct logdir *ld)
222 int fd; 222 int fd;
223 223
224 /* child */ 224 /* child */
225 signal(SIGTERM, SIG_DFL); 225 bb_signals(0
226 signal(SIGALRM, SIG_DFL); 226 + (1 << SIGTERM)
227 signal(SIGHUP, SIG_DFL); 227 + (1 << SIGALRM)
228 + (1 << SIGHUP)
229 , SIG_DFL);
228 sig_unblock(SIGTERM); 230 sig_unblock(SIGTERM);
229 sig_unblock(SIGALRM); 231 sig_unblock(SIGALRM);
230 sig_unblock(SIGHUP); 232 sig_unblock(SIGHUP);
@@ -903,10 +905,10 @@ int svlogd_main(int argc, char **argv)
903 sigaddset(&blocked_sigset, SIGALRM); 905 sigaddset(&blocked_sigset, SIGALRM);
904 sigaddset(&blocked_sigset, SIGHUP); 906 sigaddset(&blocked_sigset, SIGHUP);
905 sigprocmask(SIG_BLOCK, &blocked_sigset, NULL); 907 sigprocmask(SIG_BLOCK, &blocked_sigset, NULL);
906 sig_catch(SIGTERM, sig_term_handler); 908 bb_signals_recursive(1 << SIGTERM, sig_term_handler);
907 sig_catch(SIGCHLD, sig_child_handler); 909 bb_signals_recursive(1 << SIGCHLD, sig_child_handler);
908 sig_catch(SIGALRM, sig_alarm_handler); 910 bb_signals_recursive(1 << SIGALRM, sig_alarm_handler);
909 sig_catch(SIGHUP, sig_hangup_handler); 911 bb_signals_recursive(1 << SIGHUP, sig_hangup_handler);
910 912
911 logdirs_reopen(); 913 logdirs_reopen();
912 914
diff --git a/shell/hush.c b/shell/hush.c
index 8afa15e89..4d4843173 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -709,28 +709,34 @@ static void signal_SA_RESTART(int sig, void (*handler)(int))
709/* Signals are grouped, we handle them in batches */ 709/* Signals are grouped, we handle them in batches */
710static void set_fatal_sighandler(void (*handler)(int)) 710static void set_fatal_sighandler(void (*handler)(int))
711{ 711{
712 signal(SIGILL , handler); 712 bb_signals(0
713 signal(SIGTRAP, handler); 713 + (1 << SIGILL)
714 signal(SIGABRT, handler); 714 + (1 << SIGTRAP)
715 signal(SIGFPE , handler); 715 + (1 << SIGABRT)
716 signal(SIGBUS , handler); 716 + (1 << SIGFPE)
717 signal(SIGSEGV, handler); 717 + (1 << SIGBUS)
718 + (1 << SIGSEGV)
718 /* bash 3.2 seems to handle these just like 'fatal' ones */ 719 /* bash 3.2 seems to handle these just like 'fatal' ones */
719 signal(SIGHUP , handler); 720 + (1 << SIGHUP)
720 signal(SIGPIPE, handler); 721 + (1 << SIGPIPE)
721 signal(SIGALRM, handler); 722 + (1 << SIGALRM)
723 , handler);
722} 724}
723static void set_jobctrl_sighandler(void (*handler)(int)) 725static void set_jobctrl_sighandler(void (*handler)(int))
724{ 726{
725 signal(SIGTSTP, handler); 727 bb_signals(0
726 signal(SIGTTIN, handler); 728 + (1 << SIGTSTP)
727 signal(SIGTTOU, handler); 729 + (1 << SIGTTIN)
730 + (1 << SIGTTOU)
731 , handler);
728} 732}
729static void set_misc_sighandler(void (*handler)(int)) 733static void set_misc_sighandler(void (*handler)(int))
730{ 734{
731 signal(SIGINT , handler); 735 bb_signals(0
732 signal(SIGQUIT, handler); 736 + (1 << SIGINT)
733 signal(SIGTERM, handler); 737 + (1 << SIGQUIT)
738 + (1 << SIGTERM)
739 , handler);
734} 740}
735/* SIGCHLD is special and handled separately */ 741/* SIGCHLD is special and handled separately */
736 742
diff --git a/sysklogd/klogd.c b/sysklogd/klogd.c
index d65b6f9a0..6a675b8b3 100644
--- a/sysklogd/klogd.c
+++ b/sysklogd/klogd.c
@@ -57,9 +57,10 @@ int klogd_main(int argc, char **argv)
57 openlog("kernel", 0, LOG_KERN); 57 openlog("kernel", 0, LOG_KERN);
58 58
59 /* Set up sig handlers */ 59 /* Set up sig handlers */
60 signal(SIGINT, klogd_signal); 60 bb_signals(0
61 signal(SIGKILL, klogd_signal); 61 + (1 << SIGINT)
62 signal(SIGTERM, klogd_signal); 62 + (1 << SIGTERM)
63 , klogd_signal);
63 signal(SIGHUP, SIG_IGN); 64 signal(SIGHUP, SIG_IGN);
64 65
65 /* "Open the log. Currently a NOP." */ 66 /* "Open the log. Currently a NOP." */
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c
index 457f38103..c6e057138 100644
--- a/sysklogd/syslogd.c
+++ b/sysklogd/syslogd.c
@@ -540,9 +540,11 @@ static void do_syslogd(void)
540 int sock_fd; 540 int sock_fd;
541 541
542 /* Set up signal handlers */ 542 /* Set up signal handlers */
543 signal(SIGINT, quit_signal); 543 bb_signals(0
544 signal(SIGTERM, quit_signal); 544 + (1 << SIGINT)
545 signal(SIGQUIT, quit_signal); 545 + (1 << SIGTERM)
546 + (1 << SIGQUIT)
547 , quit_signal);
546 signal(SIGHUP, SIG_IGN); 548 signal(SIGHUP, SIG_IGN);
547 /* signal(SIGCHLD, SIG_IGN); - why? */ 549 /* signal(SIGCHLD, SIG_IGN); - why? */
548#ifdef SYSLOGD_MARK 550#ifdef SYSLOGD_MARK
diff --git a/util-linux/more.c b/util-linux/more.c
index 2d7f3a9e4..eeeea509e 100644
--- a/util-linux/more.c
+++ b/util-linux/more.c
@@ -87,9 +87,11 @@ int more_main(int argc, char **argv)
87 new_settings.c_cc[VMIN] = 1; 87 new_settings.c_cc[VMIN] = 1;
88 new_settings.c_cc[VTIME] = 0; 88 new_settings.c_cc[VTIME] = 0;
89 setTermSettings(cin_fileno, &new_settings); 89 setTermSettings(cin_fileno, &new_settings);
90 signal(SIGINT, gotsig); 90 bb_signals(0
91 signal(SIGQUIT, gotsig); 91 + (1 << SIGINT)
92 signal(SIGTERM, gotsig); 92 + (1 << SIGQUIT)
93 + (1 << SIGTERM)
94 , gotsig);
93#endif 95#endif
94 96
95 do { 97 do {