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 #if 0 /// UNNEEDED by elogind
77 int sigaction_many(const struct sigaction *sa, ...) {
82 r = sigaction_many_ap(sa, 0, ap);
89 int ignore_signals(int sig, ...) {
91 static const struct sigaction sa = {
92 .sa_handler = SIG_IGN,
93 .sa_flags = SA_RESTART,
100 r = sigaction_many_ap(&sa, sig, ap);
106 int default_signals(int sig, ...) {
108 static const struct sigaction sa = {
109 .sa_handler = SIG_DFL,
110 .sa_flags = SA_RESTART,
117 r = sigaction_many_ap(&sa, sig, ap);
123 static int sigset_add_many_ap(sigset_t *ss, va_list ap) {
128 while ((sig = va_arg(ap, int)) >= 0) {
133 if (sigaddset(ss, sig) < 0) {
142 int sigset_add_many(sigset_t *ss, ...) {
147 r = sigset_add_many_ap(ss, ap);
153 int sigprocmask_many(int how, sigset_t *old, ...) {
158 if (sigemptyset(&ss) < 0)
162 r = sigset_add_many_ap(&ss, ap);
168 if (sigprocmask(how, &ss, old) < 0)
174 static const char *const __signal_table[] = {
191 [SIGSTKFLT] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */
202 [SIGVTALRM] = "VTALRM",
204 [SIGWINCH] = "WINCH",
210 DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int);
212 const char *signal_to_string(int signo) {
213 static thread_local char buf[STRLEN("RTMIN+") + DECIMAL_STR_MAX(int) + 1];
216 name = __signal_to_string(signo);
220 if (signo >= SIGRTMIN && signo <= SIGRTMAX)
221 xsprintf(buf, "RTMIN+%d", signo - SIGRTMIN);
223 xsprintf(buf, "%d", signo);
228 int signal_from_string(const char *s) {
232 /* Check that the input is a signal number. */
233 if (safe_atoi(s, &signo) >= 0) {
234 if (SIGNAL_VALID(signo))
240 /* Drop "SIG" prefix. */
241 if (startswith(s, "SIG"))
244 /* Check that the input is a signal name. */
245 signo = __signal_from_string(s);
249 /* Check that the input is RTMIN or
250 * RTMIN+n (0 <= n <= SIGRTMAX-SIGRTMIN). */
251 p = startswith(s, "RTMIN");
258 r = safe_atoi(p, &signo);
262 if (signo < 0 || signo > SIGRTMAX - SIGRTMIN)
265 return signo + SIGRTMIN;
268 /* Check that the input is RTMAX or
269 * RTMAX-n (0 <= n <= SIGRTMAX-SIGRTMIN). */
270 p = startswith(s, "RTMAX");
277 r = safe_atoi(p, &signo);
281 if (signo > 0 || signo < SIGRTMIN - SIGRTMAX)
284 return signo + SIGRTMAX;
291 #if 0 /// UNNEEDED by elogind
292 void nop_signal_handler(int sig) {