blob: d3d84ef6a74176f94f84e0e0d9b9389b9f41b6a8 [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 */
Denis Vlasenko25591c32008-02-16 22:58:56 +000011#include "libbb.h"
12
Denis Vlasenko08ea11a2008-09-11 19:51:11 +000013/* All known arches use small ints for signals */
14smallint bb_got_signal;
15
16void record_signo(int signo)
17{
18 bb_got_signal = signo;
19}
20
Denis Vlasenko8e2cfec2008-03-12 23:19:35 +000021/* Saves 2 bytes on x86! Oh my... */
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000022int FAST_FUNC sigaction_set(int signum, const struct sigaction *act)
Denis Vlasenko8e2cfec2008-03-12 23:19:35 +000023{
24 return sigaction(signum, act, NULL);
25}
26
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000027int FAST_FUNC sigprocmask_allsigs(int how)
Denis Vlasenko3f165fa2008-03-17 08:29:08 +000028{
29 sigset_t set;
30 sigfillset(&set);
31 return sigprocmask(how, &set, NULL);
32}
33
Denys Vlasenkob437df12018-12-08 15:35:24 +010034int FAST_FUNC sigprocmask2(int how, sigset_t *set)
Denys Vlasenko136fe9b2018-12-08 13:49:15 +010035{
36 // Grr... gcc 8.1.1:
37 // "passing argument 3 to restrict-qualified parameter aliases with argument 2"
38 // dance around that...
39 sigset_t *oset FIX_ALIASING;
40 oset = set;
Denys Vlasenkob437df12018-12-08 15:35:24 +010041 return sigprocmask(how, set, oset);
Denys Vlasenko136fe9b2018-12-08 13:49:15 +010042}
43
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000044void FAST_FUNC bb_signals(int sigs, void (*f)(int))
Denis Vlasenko25591c32008-02-16 22:58:56 +000045{
46 int sig_no = 0;
47 int bit = 1;
48
49 while (sigs) {
50 if (sigs & bit) {
Denys Vlasenkoc4f2d992012-09-27 13:20:34 +020051 sigs -= bit;
Denis Vlasenko25591c32008-02-16 22:58:56 +000052 signal(sig_no, f);
53 }
54 sig_no++;
55 bit <<= 1;
56 }
57}
58
Denis Vlasenkocab28aa2009-01-31 01:02:07 +000059void FAST_FUNC bb_signals_recursive_norestart(int sigs, void (*f)(int))
Denis Vlasenko25591c32008-02-16 22:58:56 +000060{
61 int sig_no = 0;
62 int bit = 1;
63 struct sigaction sa;
64
65 memset(&sa, 0, sizeof(sa));
66 sa.sa_handler = f;
67 /*sa.sa_flags = 0;*/
68 /*sigemptyset(&sa.sa_mask); - hope memset did it*/
69
70 while (sigs) {
71 if (sigs & bit) {
Denys Vlasenkoc4f2d992012-09-27 13:20:34 +020072 sigs -= bit;
Denis Vlasenko8e2cfec2008-03-12 23:19:35 +000073 sigaction_set(sig_no, &sa);
Denis Vlasenko25591c32008-02-16 22:58:56 +000074 }
75 sig_no++;
76 bit <<= 1;
77 }
78}
79
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000080void FAST_FUNC sig_block(int sig)
Denis Vlasenko25591c32008-02-16 22:58:56 +000081{
82 sigset_t ss;
83 sigemptyset(&ss);
84 sigaddset(&ss, sig);
85 sigprocmask(SIG_BLOCK, &ss, NULL);
86}
87
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000088void FAST_FUNC sig_unblock(int sig)
Denis Vlasenko25591c32008-02-16 22:58:56 +000089{
90 sigset_t ss;
91 sigemptyset(&ss);
92 sigaddset(&ss, sig);
93 sigprocmask(SIG_UNBLOCK, &ss, NULL);
94}
95
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000096void FAST_FUNC wait_for_any_sig(void)
Denis Vlasenko25591c32008-02-16 22:58:56 +000097{
98 sigset_t ss;
99 sigemptyset(&ss);
100 sigsuspend(&ss);
101}
Denis Vlasenko400d8bb2008-02-24 13:36:01 +0000102
103/* Assuming the sig is fatal */
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +0000104void FAST_FUNC kill_myself_with_sig(int sig)
Denis Vlasenko400d8bb2008-02-24 13:36:01 +0000105{
Denis Vlasenko400d8bb2008-02-24 13:36:01 +0000106 signal(sig, SIG_DFL);
Denis Vlasenko4cf1d082008-03-12 23:13:50 +0000107 sig_unblock(sig);
Denis Vlasenko400d8bb2008-02-24 13:36:01 +0000108 raise(sig);
Denys Vlasenkoc4f2d992012-09-27 13:20:34 +0200109 _exit(sig | 128); /* Should not reach it */
Denis Vlasenko400d8bb2008-02-24 13:36:01 +0000110}
Denis Vlasenko8e2cfec2008-03-12 23:19:35 +0000111
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +0000112void FAST_FUNC signal_SA_RESTART_empty_mask(int sig, void (*handler)(int))
Denis Vlasenko8e2cfec2008-03-12 23:19:35 +0000113{
114 struct sigaction sa;
115 memset(&sa, 0, sizeof(sa));
116 /*sigemptyset(&sa.sa_mask);*/
117 sa.sa_flags = SA_RESTART;
118 sa.sa_handler = handler;
119 sigaction_set(sig, &sa);
120}
121
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +0000122void FAST_FUNC signal_no_SA_RESTART_empty_mask(int sig, void (*handler)(int))
Denis Vlasenko8e2cfec2008-03-12 23:19:35 +0000123{
124 struct sigaction sa;
125 memset(&sa, 0, sizeof(sa));
126 /*sigemptyset(&sa.sa_mask);*/
127 /*sa.sa_flags = 0;*/
128 sa.sa_handler = handler;
129 sigaction_set(sig, &sa);
130}