1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2015 Lennart Poettering
13 #include "parse-util.h"
14 #include "signal-util.h"
15 #include "stdio-util.h"
16 #include "string-table.h"
17 #include "string-util.h"
19 int reset_all_signal_handlers(void) {
20 static const struct sigaction sa = {
21 .sa_handler = SIG_DFL,
22 .sa_flags = SA_RESTART,
26 for (sig = 1; sig < _NSIG; sig++) {
28 /* These two cannot be caught... */
29 if (IN_SET(sig, SIGKILL, SIGSTOP))
32 /* On Linux the first two RT signals are reserved by
33 * glibc, and sigaction() will return EINVAL for them. */
34 if ((sigaction(sig, &sa, NULL) < 0))
35 if (errno != EINVAL && r >= 0)
42 int reset_signal_mask(void) {
45 if (sigemptyset(&ss) < 0)
48 if (sigprocmask(SIG_SETMASK, &ss, NULL) < 0)
54 static int sigaction_many_ap(const struct sigaction *sa, int sig, va_list ap) {
57 /* negative signal ends the list. 0 signal is skipped. */
63 if (sigaction(sig, sa, NULL) < 0)
67 while ((sig = va_arg(ap, int)) >= 0) {
72 if (sigaction(sig, sa, NULL) < 0) {
81 #if 0 /// UNNEEDED by elogind
82 int sigaction_many(const struct sigaction *sa, ...) {
87 r = sigaction_many_ap(sa, 0, ap);
94 int ignore_signals(int sig, ...) {
96 static const struct sigaction sa = {
97 .sa_handler = SIG_IGN,
98 .sa_flags = SA_RESTART,
105 r = sigaction_many_ap(&sa, sig, ap);
111 int default_signals(int sig, ...) {
113 static const struct sigaction sa = {
114 .sa_handler = SIG_DFL,
115 .sa_flags = SA_RESTART,
122 r = sigaction_many_ap(&sa, sig, ap);
128 static int sigset_add_many_ap(sigset_t *ss, va_list ap) {
133 while ((sig = va_arg(ap, int)) >= 0) {
138 if (sigaddset(ss, sig) < 0) {
147 int sigset_add_many(sigset_t *ss, ...) {
152 r = sigset_add_many_ap(ss, ap);
158 int sigprocmask_many(int how, sigset_t *old, ...) {
163 if (sigemptyset(&ss) < 0)
167 r = sigset_add_many_ap(&ss, ap);
173 if (sigprocmask(how, &ss, old) < 0)
179 static const char *const __signal_table[] = {
196 [SIGSTKFLT] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */
207 [SIGVTALRM] = "VTALRM",
209 [SIGWINCH] = "WINCH",
215 DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int);
217 const char *signal_to_string(int signo) {
218 static thread_local char buf[STRLEN("RTMIN+") + DECIMAL_STR_MAX(int) + 1];
221 name = __signal_to_string(signo);
225 if (signo >= SIGRTMIN && signo <= SIGRTMAX)
226 xsprintf(buf, "RTMIN+%d", signo - SIGRTMIN);
228 xsprintf(buf, "%d", signo);
233 int signal_from_string(const char *s) {
237 /* Check that the input is a signal number. */
238 if (safe_atoi(s, &signo) >= 0) {
239 if (SIGNAL_VALID(signo))
245 /* Drop "SIG" prefix. */
246 if (startswith(s, "SIG"))
249 /* Check that the input is a signal name. */
250 signo = __signal_from_string(s);
254 /* Check that the input is RTMIN or
255 * RTMIN+n (0 <= n <= SIGRTMAX-SIGRTMIN). */
256 p = startswith(s, "RTMIN");
263 r = safe_atoi(p, &signo);
267 if (signo < 0 || signo > SIGRTMAX - SIGRTMIN)
270 return signo + SIGRTMIN;
273 /* Check that the input is RTMAX or
274 * RTMAX-n (0 <= n <= SIGRTMAX-SIGRTMIN). */
275 p = startswith(s, "RTMAX");
282 r = safe_atoi(p, &signo);
286 if (signo > 0 || signo < SIGRTMIN - SIGRTMAX)
289 return signo + SIGRTMAX;
296 #if 0 /// UNNEEDED by elogind
297 void nop_signal_handler(int sig) {