1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 Copyright 2015 Lennart Poettering
11 #include "parse-util.h"
12 #include "signal-util.h"
13 #include "stdio-util.h"
14 #include "string-table.h"
15 #include "string-util.h"
17 int reset_all_signal_handlers(void) {
18 static const struct sigaction sa = {
19 .sa_handler = SIG_DFL,
20 .sa_flags = SA_RESTART,
24 for (sig = 1; sig < _NSIG; sig++) {
26 /* These two cannot be caught... */
27 if (IN_SET(sig, SIGKILL, SIGSTOP))
30 /* On Linux the first two RT signals are reserved by
31 * glibc, and sigaction() will return EINVAL for them. */
32 if ((sigaction(sig, &sa, NULL) < 0))
33 if (errno != EINVAL && r >= 0)
40 int reset_signal_mask(void) {
43 if (sigemptyset(&ss) < 0)
46 if (sigprocmask(SIG_SETMASK, &ss, NULL) < 0)
52 static int sigaction_many_ap(const struct sigaction *sa, int sig, va_list ap) {
55 /* negative signal ends the list. 0 signal is skipped. */
61 if (sigaction(sig, sa, NULL) < 0)
65 while ((sig = va_arg(ap, int)) >= 0) {
70 if (sigaction(sig, sa, NULL) < 0) {
79 #if 0 /// UNNEEDED by elogind
80 int sigaction_many(const struct sigaction *sa, ...) {
85 r = sigaction_many_ap(sa, 0, ap);
92 int ignore_signals(int sig, ...) {
94 static const struct sigaction sa = {
95 .sa_handler = SIG_IGN,
96 .sa_flags = SA_RESTART,
103 r = sigaction_many_ap(&sa, sig, ap);
109 int default_signals(int sig, ...) {
111 static const struct sigaction sa = {
112 .sa_handler = SIG_DFL,
113 .sa_flags = SA_RESTART,
120 r = sigaction_many_ap(&sa, sig, ap);
126 static int sigset_add_many_ap(sigset_t *ss, va_list ap) {
131 while ((sig = va_arg(ap, int)) >= 0) {
136 if (sigaddset(ss, sig) < 0) {
145 int sigset_add_many(sigset_t *ss, ...) {
150 r = sigset_add_many_ap(ss, ap);
156 int sigprocmask_many(int how, sigset_t *old, ...) {
161 if (sigemptyset(&ss) < 0)
165 r = sigset_add_many_ap(&ss, ap);
171 if (sigprocmask(how, &ss, old) < 0)
177 static const char *const __signal_table[] = {
194 [SIGSTKFLT] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */
205 [SIGVTALRM] = "VTALRM",
207 [SIGWINCH] = "WINCH",
213 DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int);
215 const char *signal_to_string(int signo) {
216 static thread_local char buf[STRLEN("RTMIN+") + DECIMAL_STR_MAX(int) + 1];
219 name = __signal_to_string(signo);
223 if (signo >= SIGRTMIN && signo <= SIGRTMAX)
224 xsprintf(buf, "RTMIN+%d", signo - SIGRTMIN);
226 xsprintf(buf, "%d", signo);
231 int signal_from_string(const char *s) {
235 /* Check that the input is a signal number. */
236 if (safe_atoi(s, &signo) >= 0) {
237 if (SIGNAL_VALID(signo))
243 /* Drop "SIG" prefix. */
244 if (startswith(s, "SIG"))
247 /* Check that the input is a signal name. */
248 signo = __signal_from_string(s);
252 /* Check that the input is RTMIN or
253 * RTMIN+n (0 <= n <= SIGRTMAX-SIGRTMIN). */
254 p = startswith(s, "RTMIN");
261 r = safe_atoi(p, &signo);
265 if (signo < 0 || signo > SIGRTMAX - SIGRTMIN)
268 return signo + SIGRTMIN;
271 /* Check that the input is RTMAX or
272 * RTMAX-n (0 <= n <= SIGRTMAX-SIGRTMIN). */
273 p = startswith(s, "RTMAX");
280 r = safe_atoi(p, &signo);
284 if (signo > 0 || signo < SIGRTMIN - SIGRTMAX)
287 return signo + SIGRTMAX;
294 #if 0 /// UNNEEDED by elogind
295 void nop_signal_handler(int sig) {