]>
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 "parse-util.h"
23 #include "signal-util.h"
24 #include "string-table.h"
25 #include "string-util.h"
28 int reset_all_signal_handlers(void) {
29 static const struct sigaction sa
= {
30 .sa_handler
= SIG_DFL
,
31 .sa_flags
= SA_RESTART
,
35 for (sig
= 1; sig
< _NSIG
; sig
++) {
37 /* These two cannot be caught... */
38 if (sig
== SIGKILL
|| sig
== SIGSTOP
)
41 /* On Linux the first two RT signals are reserved by
42 * glibc, and sigaction() will return EINVAL for them. */
43 if ((sigaction(sig
, &sa
, NULL
) < 0))
44 if (errno
!= EINVAL
&& r
>= 0)
51 int reset_signal_mask(void) {
54 if (sigemptyset(&ss
) < 0)
57 if (sigprocmask(SIG_SETMASK
, &ss
, NULL
) < 0)
63 static int sigaction_many_ap(const struct sigaction
*sa
, int sig
, va_list ap
) {
66 /* negative signal ends the list. 0 signal is skipped. */
72 if (sigaction(sig
, sa
, NULL
) < 0)
76 while ((sig
= va_arg(ap
, int)) >= 0) {
81 if (sigaction(sig
, sa
, NULL
) < 0) {
90 int sigaction_many(const struct sigaction
*sa
, ...) {
95 r
= sigaction_many_ap(sa
, 0, ap
);
101 int ignore_signals(int sig
, ...) {
103 static const struct sigaction sa
= {
104 .sa_handler
= SIG_IGN
,
105 .sa_flags
= SA_RESTART
,
112 r
= sigaction_many_ap(&sa
, sig
, ap
);
118 int default_signals(int sig
, ...) {
120 static const struct sigaction sa
= {
121 .sa_handler
= SIG_DFL
,
122 .sa_flags
= SA_RESTART
,
129 r
= sigaction_many_ap(&sa
, sig
, ap
);
135 static int sigset_add_many_ap(sigset_t
*ss
, va_list ap
) {
140 while ((sig
= va_arg(ap
, int)) >= 0) {
145 if (sigaddset(ss
, sig
) < 0) {
154 int sigset_add_many(sigset_t
*ss
, ...) {
159 r
= sigset_add_many_ap(ss
, ap
);
165 int sigprocmask_many(int how
, sigset_t
*old
, ...) {
170 if (sigemptyset(&ss
) < 0)
174 r
= sigset_add_many_ap(&ss
, ap
);
180 if (sigprocmask(how
, &ss
, old
) < 0)
186 static const char *const __signal_table
[] = {
203 [SIGSTKFLT
] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */
214 [SIGVTALRM
] = "VTALRM",
216 [SIGWINCH
] = "WINCH",
222 DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal
, int);
224 const char *signal_to_string(int signo
) {
225 static thread_local
char buf
[sizeof("RTMIN+")-1 + DECIMAL_STR_MAX(int) + 1];
228 name
= __signal_to_string(signo
);
232 if (signo
>= SIGRTMIN
&& signo
<= SIGRTMAX
)
233 snprintf(buf
, sizeof(buf
), "RTMIN+%d", signo
- SIGRTMIN
);
235 snprintf(buf
, sizeof(buf
), "%d", signo
);
240 int signal_from_string(const char *s
) {
245 signo
= __signal_from_string(s
);
249 if (startswith(s
, "RTMIN+")) {
253 if (safe_atou(s
, &u
) >= 0) {
254 signo
= (int) u
+ offset
;
255 if (signo
> 0 && signo
< _NSIG
)
261 int signal_from_string_try_harder(const char *s
) {
265 signo
= signal_from_string(s
);
267 if (startswith(s
, "SIG"))
268 return signal_from_string(s
+3);
273 void nop_signal_handler(int sig
) {