]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/signal-util.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2015 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include "string-util.h"
25 #include "signal-util.h"
27 int reset_all_signal_handlers(void) {
28 static const struct sigaction sa
= {
29 .sa_handler
= SIG_DFL
,
30 .sa_flags
= SA_RESTART
,
34 for (sig
= 1; sig
< _NSIG
; sig
++) {
36 /* These two cannot be caught... */
37 if (sig
== SIGKILL
|| sig
== SIGSTOP
)
40 /* On Linux the first two RT signals are reserved by
41 * glibc, and sigaction() will return EINVAL for them. */
42 if ((sigaction(sig
, &sa
, NULL
) < 0))
43 if (errno
!= EINVAL
&& r
>= 0)
50 int reset_signal_mask(void) {
53 if (sigemptyset(&ss
) < 0)
56 if (sigprocmask(SIG_SETMASK
, &ss
, NULL
) < 0)
62 static int sigaction_many_ap(const struct sigaction
*sa
, int sig
, va_list ap
) {
65 /* negative signal ends the list. 0 signal is skipped. */
71 if (sigaction(sig
, sa
, NULL
) < 0)
75 while ((sig
= va_arg(ap
, int)) >= 0) {
80 if (sigaction(sig
, sa
, NULL
) < 0) {
89 int sigaction_many(const struct sigaction
*sa
, ...) {
94 r
= sigaction_many_ap(sa
, 0, ap
);
100 int ignore_signals(int sig
, ...) {
102 static const struct sigaction sa
= {
103 .sa_handler
= SIG_IGN
,
104 .sa_flags
= SA_RESTART
,
111 r
= sigaction_many_ap(&sa
, sig
, ap
);
117 int default_signals(int sig
, ...) {
119 static const struct sigaction sa
= {
120 .sa_handler
= SIG_DFL
,
121 .sa_flags
= SA_RESTART
,
128 r
= sigaction_many_ap(&sa
, sig
, ap
);
134 static int sigset_add_many_ap(sigset_t
*ss
, va_list ap
) {
139 while ((sig
= va_arg(ap
, int)) >= 0) {
144 if (sigaddset(ss
, sig
) < 0) {
153 int sigset_add_many(sigset_t
*ss
, ...) {
158 r
= sigset_add_many_ap(ss
, ap
);
164 int sigprocmask_many(int how
, sigset_t
*old
, ...) {
169 if (sigemptyset(&ss
) < 0)
173 r
= sigset_add_many_ap(&ss
, ap
);
179 if (sigprocmask(how
, &ss
, old
) < 0)
185 static const char *const __signal_table
[] = {
202 [SIGSTKFLT
] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */
213 [SIGVTALRM
] = "VTALRM",
215 [SIGWINCH
] = "WINCH",
221 DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal
, int);
223 const char *signal_to_string(int signo
) {
224 static thread_local
char buf
[sizeof("RTMIN+")-1 + DECIMAL_STR_MAX(int) + 1];
227 name
= __signal_to_string(signo
);
231 if (signo
>= SIGRTMIN
&& signo
<= SIGRTMAX
)
232 snprintf(buf
, sizeof(buf
), "RTMIN+%d", signo
- SIGRTMIN
);
234 snprintf(buf
, sizeof(buf
), "%d", signo
);
239 int signal_from_string(const char *s
) {
244 signo
= __signal_from_string(s
);
248 if (startswith(s
, "RTMIN+")) {
252 if (safe_atou(s
, &u
) >= 0) {
253 signo
= (int) u
+ offset
;
254 if (signo
> 0 && signo
< _NSIG
)
260 int signal_from_string_try_harder(const char *s
) {
264 signo
= signal_from_string(s
);
266 if (startswith(s
, "SIG"))
267 return signal_from_string(s
+3);