]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/signal-util.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
8 #include "parse-util.h"
9 #include "signal-util.h"
10 #include "stdio-util.h"
11 #include "string-table.h"
12 #include "string-util.h"
14 int reset_all_signal_handlers(void) {
15 static const struct sigaction sa
= {
16 .sa_handler
= SIG_DFL
,
17 .sa_flags
= SA_RESTART
,
21 for (sig
= 1; sig
< _NSIG
; sig
++) {
23 /* These two cannot be caught... */
24 if (IN_SET(sig
, SIGKILL
, SIGSTOP
))
27 /* On Linux the first two RT signals are reserved by
28 * glibc, and sigaction() will return EINVAL for them. */
29 if ((sigaction(sig
, &sa
, NULL
) < 0))
30 if (errno
!= EINVAL
&& r
>= 0)
37 int reset_signal_mask(void) {
40 if (sigemptyset(&ss
) < 0)
43 if (sigprocmask(SIG_SETMASK
, &ss
, NULL
) < 0)
49 static int sigaction_many_ap(const struct sigaction
*sa
, int sig
, va_list ap
) {
52 /* negative signal ends the list. 0 signal is skipped. */
58 if (sigaction(sig
, sa
, NULL
) < 0)
62 while ((sig
= va_arg(ap
, int)) >= 0) {
67 if (sigaction(sig
, sa
, NULL
) < 0) {
76 int sigaction_many(const struct sigaction
*sa
, ...) {
81 r
= sigaction_many_ap(sa
, 0, ap
);
87 int ignore_signals(int sig
, ...) {
89 static const struct sigaction sa
= {
90 .sa_handler
= SIG_IGN
,
91 .sa_flags
= SA_RESTART
,
98 r
= sigaction_many_ap(&sa
, sig
, ap
);
104 int default_signals(int sig
, ...) {
106 static const struct sigaction sa
= {
107 .sa_handler
= SIG_DFL
,
108 .sa_flags
= SA_RESTART
,
115 r
= sigaction_many_ap(&sa
, sig
, ap
);
121 static int sigset_add_many_ap(sigset_t
*ss
, va_list ap
) {
126 while ((sig
= va_arg(ap
, int)) >= 0) {
131 if (sigaddset(ss
, sig
) < 0) {
140 int sigset_add_many(sigset_t
*ss
, ...) {
145 r
= sigset_add_many_ap(ss
, ap
);
151 int sigprocmask_many(int how
, sigset_t
*old
, ...) {
156 if (sigemptyset(&ss
) < 0)
160 r
= sigset_add_many_ap(&ss
, ap
);
166 if (sigprocmask(how
, &ss
, old
) < 0)
172 static const char *const __signal_table
[] = {
189 [SIGSTKFLT
] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */
200 [SIGVTALRM
] = "VTALRM",
202 [SIGWINCH
] = "WINCH",
208 DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal
, int);
210 const char *signal_to_string(int signo
) {
211 static thread_local
char buf
[STRLEN("RTMIN+") + DECIMAL_STR_MAX(int) + 1];
214 name
= __signal_to_string(signo
);
218 if (signo
>= SIGRTMIN
&& signo
<= SIGRTMAX
)
219 xsprintf(buf
, "RTMIN+%d", signo
- SIGRTMIN
);
221 xsprintf(buf
, "%d", signo
);
226 int signal_from_string(const char *s
) {
230 /* Check that the input is a signal number. */
231 if (safe_atoi(s
, &signo
) >= 0) {
232 if (SIGNAL_VALID(signo
))
238 /* Drop "SIG" prefix. */
239 if (startswith(s
, "SIG"))
242 /* Check that the input is a signal name. */
243 signo
= __signal_from_string(s
);
247 /* Check that the input is RTMIN or
248 * RTMIN+n (0 <= n <= SIGRTMAX-SIGRTMIN). */
249 p
= startswith(s
, "RTMIN");
256 r
= safe_atoi(p
, &signo
);
260 if (signo
< 0 || signo
> SIGRTMAX
- SIGRTMIN
)
263 return signo
+ SIGRTMIN
;
266 /* Check that the input is RTMAX or
267 * RTMAX-n (0 <= n <= SIGRTMAX-SIGRTMIN). */
268 p
= startswith(s
, "RTMAX");
275 r
= safe_atoi(p
, &signo
);
279 if (signo
> 0 || signo
< SIGRTMIN
- SIGRTMAX
)
282 return signo
+ SIGRTMAX
;
288 void nop_signal_handler(int sig
) {