]>
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/>.
27 #include "parse-util.h"
28 #include "signal-util.h"
29 #include "stdio-util.h"
30 #include "string-table.h"
31 #include "string-util.h"
33 int reset_all_signal_handlers(void) {
34 static const struct sigaction sa
= {
35 .sa_handler
= SIG_DFL
,
36 .sa_flags
= SA_RESTART
,
40 for (sig
= 1; sig
< _NSIG
; sig
++) {
42 /* These two cannot be caught... */
43 if (sig
== SIGKILL
|| sig
== SIGSTOP
)
46 /* On Linux the first two RT signals are reserved by
47 * glibc, and sigaction() will return EINVAL for them. */
48 if ((sigaction(sig
, &sa
, NULL
) < 0))
49 if (errno
!= EINVAL
&& r
>= 0)
56 int reset_signal_mask(void) {
59 if (sigemptyset(&ss
) < 0)
62 if (sigprocmask(SIG_SETMASK
, &ss
, NULL
) < 0)
68 static int sigaction_many_ap(const struct sigaction
*sa
, int sig
, va_list ap
) {
71 /* negative signal ends the list. 0 signal is skipped. */
77 if (sigaction(sig
, sa
, NULL
) < 0)
81 while ((sig
= va_arg(ap
, int)) >= 0) {
86 if (sigaction(sig
, sa
, NULL
) < 0) {
95 int sigaction_many(const struct sigaction
*sa
, ...) {
100 r
= sigaction_many_ap(sa
, 0, ap
);
106 int ignore_signals(int sig
, ...) {
108 static const struct sigaction sa
= {
109 .sa_handler
= SIG_IGN
,
110 .sa_flags
= SA_RESTART
,
117 r
= sigaction_many_ap(&sa
, sig
, ap
);
123 int default_signals(int sig
, ...) {
125 static const struct sigaction sa
= {
126 .sa_handler
= SIG_DFL
,
127 .sa_flags
= SA_RESTART
,
134 r
= sigaction_many_ap(&sa
, sig
, ap
);
140 static int sigset_add_many_ap(sigset_t
*ss
, va_list ap
) {
145 while ((sig
= va_arg(ap
, int)) >= 0) {
150 if (sigaddset(ss
, sig
) < 0) {
159 int sigset_add_many(sigset_t
*ss
, ...) {
164 r
= sigset_add_many_ap(ss
, ap
);
170 int sigprocmask_many(int how
, sigset_t
*old
, ...) {
175 if (sigemptyset(&ss
) < 0)
179 r
= sigset_add_many_ap(&ss
, ap
);
185 if (sigprocmask(how
, &ss
, old
) < 0)
191 static const char *const __signal_table
[] = {
208 [SIGSTKFLT
] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */
219 [SIGVTALRM
] = "VTALRM",
221 [SIGWINCH
] = "WINCH",
227 DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal
, int);
229 const char *signal_to_string(int signo
) {
230 static thread_local
char buf
[sizeof("RTMIN+")-1 + DECIMAL_STR_MAX(int) + 1];
233 name
= __signal_to_string(signo
);
237 if (signo
>= SIGRTMIN
&& signo
<= SIGRTMAX
)
238 xsprintf(buf
, "RTMIN+%d", signo
- SIGRTMIN
);
240 xsprintf(buf
, "%d", signo
);
245 int signal_from_string(const char *s
) {
250 signo
= __signal_from_string(s
);
254 if (startswith(s
, "RTMIN+")) {
258 if (safe_atou(s
, &u
) >= 0) {
259 signo
= (int) u
+ offset
;
260 if (signo
> 0 && signo
< _NSIG
)
266 int signal_from_string_try_harder(const char *s
) {
270 signo
= signal_from_string(s
);
272 if (startswith(s
, "SIG"))
273 return signal_from_string(s
+3);
278 void nop_signal_handler(int sig
) {