]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/signal-util.c
2 This file is part of systemd.
4 Copyright 2015 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
25 #include "parse-util.h"
26 #include "signal-util.h"
27 #include "stdio-util.h"
28 #include "string-table.h"
29 #include "string-util.h"
31 int reset_all_signal_handlers(void) {
32 static const struct sigaction sa
= {
33 .sa_handler
= SIG_DFL
,
34 .sa_flags
= SA_RESTART
,
38 for (sig
= 1; sig
< _NSIG
; sig
++) {
40 /* These two cannot be caught... */
41 if (sig
== SIGKILL
|| sig
== SIGSTOP
)
44 /* On Linux the first two RT signals are reserved by
45 * glibc, and sigaction() will return EINVAL for them. */
46 if ((sigaction(sig
, &sa
, NULL
) < 0))
47 if (errno
!= EINVAL
&& r
>= 0)
54 int reset_signal_mask(void) {
57 if (sigemptyset(&ss
) < 0)
60 if (sigprocmask(SIG_SETMASK
, &ss
, NULL
) < 0)
66 static int sigaction_many_ap(const struct sigaction
*sa
, int sig
, va_list ap
) {
69 /* negative signal ends the list. 0 signal is skipped. */
75 if (sigaction(sig
, sa
, NULL
) < 0)
79 while ((sig
= va_arg(ap
, int)) >= 0) {
84 if (sigaction(sig
, sa
, NULL
) < 0) {
93 int sigaction_many(const struct sigaction
*sa
, ...) {
98 r
= sigaction_many_ap(sa
, 0, ap
);
104 int ignore_signals(int sig
, ...) {
106 static const struct sigaction sa
= {
107 .sa_handler
= SIG_IGN
,
108 .sa_flags
= SA_RESTART
,
115 r
= sigaction_many_ap(&sa
, sig
, ap
);
121 int default_signals(int sig
, ...) {
123 static const struct sigaction sa
= {
124 .sa_handler
= SIG_DFL
,
125 .sa_flags
= SA_RESTART
,
132 r
= sigaction_many_ap(&sa
, sig
, ap
);
138 static int sigset_add_many_ap(sigset_t
*ss
, va_list ap
) {
143 while ((sig
= va_arg(ap
, int)) >= 0) {
148 if (sigaddset(ss
, sig
) < 0) {
157 int sigset_add_many(sigset_t
*ss
, ...) {
162 r
= sigset_add_many_ap(ss
, ap
);
168 int sigprocmask_many(int how
, sigset_t
*old
, ...) {
173 if (sigemptyset(&ss
) < 0)
177 r
= sigset_add_many_ap(&ss
, ap
);
183 if (sigprocmask(how
, &ss
, old
) < 0)
189 static const char *const __signal_table
[] = {
206 [SIGSTKFLT
] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */
217 [SIGVTALRM
] = "VTALRM",
219 [SIGWINCH
] = "WINCH",
225 DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal
, int);
227 const char *signal_to_string(int signo
) {
228 static thread_local
char buf
[sizeof("RTMIN+")-1 + DECIMAL_STR_MAX(int) + 1];
231 name
= __signal_to_string(signo
);
235 if (signo
>= SIGRTMIN
&& signo
<= SIGRTMAX
)
236 xsprintf(buf
, "RTMIN+%d", signo
- SIGRTMIN
);
238 xsprintf(buf
, "%d", signo
);
243 int signal_from_string(const char *s
) {
248 signo
= __signal_from_string(s
);
252 if (startswith(s
, "RTMIN+")) {
256 if (safe_atou(s
, &u
) >= 0) {
257 signo
= (int) u
+ offset
;
258 if (SIGNAL_VALID(signo
))
264 int signal_from_string_try_harder(const char *s
) {
268 signo
= signal_from_string(s
);
270 if (startswith(s
, "SIG"))
271 return signal_from_string(s
+3);
276 void nop_signal_handler(int sig
) {