blob: 56512473a2469dbd6f8ed6c4d06663d051d03b8b [file] [log] [blame]
Denis Vlasenko25591c32008-02-16 22:58:56 +00001/* 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
Denis Vlasenkod18f52b2008-03-02 12:53:15 +00007 * Copyright (C) 2006 Denys Vlasenko
Denis Vlasenko25591c32008-02-16 22:58:56 +00008 *
Denys Vlasenko0ef64bd2010-08-16 20:14:46 +02009 * Licensed under GPLv2, see file LICENSE in this source tree.
Denis Vlasenko25591c32008-02-16 22:58:56 +000010 */
11
12#include "libbb.h"
13
Denis Vlasenko08ea11a2008-09-11 19:51:11 +000014/* All known arches use small ints for signals */
15smallint bb_got_signal;
16
17void record_signo(int signo)
18{
19 bb_got_signal = signo;
20}
21
Denis Vlasenko8e2cfec2008-03-12 23:19:35 +000022/* Saves 2 bytes on x86! Oh my... */
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000023int FAST_FUNC sigaction_set(int signum, const struct sigaction *act)
Denis Vlasenko8e2cfec2008-03-12 23:19:35 +000024{
25 return sigaction(signum, act, NULL);
26}
27
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000028int FAST_FUNC sigprocmask_allsigs(int how)
Denis Vlasenko3f165fa2008-03-17 08:29:08 +000029{
30 sigset_t set;
31 sigfillset(&set);
32 return sigprocmask(how, &set, NULL);
33}
34
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000035void FAST_FUNC bb_signals(int sigs, void (*f)(int))
Denis Vlasenko25591c32008-02-16 22:58:56 +000036{
37 int sig_no = 0;
38 int bit = 1;
39
40 while (sigs) {
41 if (sigs & bit) {
Denys Vlasenkoc4f2d992012-09-27 13:20:34 +020042 sigs -= bit;
Denis Vlasenko25591c32008-02-16 22:58:56 +000043 signal(sig_no, f);
44 }
45 sig_no++;
46 bit <<= 1;
47 }
48}
49
Denis Vlasenkocab28aa2009-01-31 01:02:07 +000050void FAST_FUNC bb_signals_recursive_norestart(int sigs, void (*f)(int))
Denis Vlasenko25591c32008-02-16 22:58:56 +000051{
52 int sig_no = 0;
53 int bit = 1;
54 struct sigaction sa;
55
56 memset(&sa, 0, sizeof(sa));
57 sa.sa_handler = f;
58 /*sa.sa_flags = 0;*/
59 /*sigemptyset(&sa.sa_mask); - hope memset did it*/
60
61 while (sigs) {
62 if (sigs & bit) {
Denys Vlasenkoc4f2d992012-09-27 13:20:34 +020063 sigs -= bit;
Denis Vlasenko8e2cfec2008-03-12 23:19:35 +000064 sigaction_set(sig_no, &sa);
Denis Vlasenko25591c32008-02-16 22:58:56 +000065 }
66 sig_no++;
67 bit <<= 1;
68 }
69}
70
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000071void FAST_FUNC sig_block(int sig)
Denis Vlasenko25591c32008-02-16 22:58:56 +000072{
73 sigset_t ss;
74 sigemptyset(&ss);
75 sigaddset(&ss, sig);
76 sigprocmask(SIG_BLOCK, &ss, NULL);
77}
78
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000079void FAST_FUNC sig_unblock(int sig)
Denis Vlasenko25591c32008-02-16 22:58:56 +000080{
81 sigset_t ss;
82 sigemptyset(&ss);
83 sigaddset(&ss, sig);
84 sigprocmask(SIG_UNBLOCK, &ss, NULL);
85}
86
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000087void FAST_FUNC wait_for_any_sig(void)
Denis Vlasenko25591c32008-02-16 22:58:56 +000088{
89 sigset_t ss;
90 sigemptyset(&ss);
91 sigsuspend(&ss);
92}
Denis Vlasenko400d8bb2008-02-24 13:36:01 +000093
94/* Assuming the sig is fatal */
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000095void FAST_FUNC kill_myself_with_sig(int sig)
Denis Vlasenko400d8bb2008-02-24 13:36:01 +000096{
Denis Vlasenko400d8bb2008-02-24 13:36:01 +000097 signal(sig, SIG_DFL);
Denis Vlasenko4cf1d082008-03-12 23:13:50 +000098 sig_unblock(sig);
Denis Vlasenko400d8bb2008-02-24 13:36:01 +000099 raise(sig);
Denys Vlasenkoc4f2d992012-09-27 13:20:34 +0200100 _exit(sig | 128); /* Should not reach it */
Denis Vlasenko400d8bb2008-02-24 13:36:01 +0000101}
Denis Vlasenko8e2cfec2008-03-12 23:19:35 +0000102
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +0000103void FAST_FUNC signal_SA_RESTART_empty_mask(int sig, void (*handler)(int))
Denis Vlasenko8e2cfec2008-03-12 23:19:35 +0000104{
105 struct sigaction sa;
106 memset(&sa, 0, sizeof(sa));
107 /*sigemptyset(&sa.sa_mask);*/
108 sa.sa_flags = SA_RESTART;
109 sa.sa_handler = handler;
110 sigaction_set(sig, &sa);
111}
112
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +0000113void FAST_FUNC signal_no_SA_RESTART_empty_mask(int sig, void (*handler)(int))
Denis Vlasenko8e2cfec2008-03-12 23:19:35 +0000114{
115 struct sigaction sa;
116 memset(&sa, 0, sizeof(sa));
117 /*sigemptyset(&sa.sa_mask);*/
118 /*sa.sa_flags = 0;*/
119 sa.sa_handler = handler;
120 sigaction_set(sig, &sa);
121}