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/>.
23 #include "signal-util.h"
25 int reset_all_signal_handlers(void) {
26 static const struct sigaction sa = {
27 .sa_handler = SIG_DFL,
28 .sa_flags = SA_RESTART,
32 for (sig = 1; sig < _NSIG; sig++) {
34 /* These two cannot be caught... */
35 if (sig == SIGKILL || sig == SIGSTOP)
38 /* On Linux the first two RT signals are reserved by
39 * glibc, and sigaction() will return EINVAL for them. */
40 if ((sigaction(sig, &sa, NULL) < 0))
41 if (errno != EINVAL && r >= 0)
48 int reset_signal_mask(void) {
51 if (sigemptyset(&ss) < 0)
54 if (sigprocmask(SIG_SETMASK, &ss, NULL) < 0)
60 static int sigaction_many_ap(const struct sigaction *sa, int sig, va_list ap) {
63 /* negative signal ends the list. 0 signal is skipped. */
69 if (sigaction(sig, sa, NULL) < 0)
73 while ((sig = va_arg(ap, int)) >= 0) {
78 if (sigaction(sig, sa, NULL) < 0) {
87 int sigaction_many(const struct sigaction *sa, ...) {
92 r = sigaction_many_ap(sa, 0, ap);
98 int ignore_signals(int sig, ...) {
100 static const struct sigaction sa = {
101 .sa_handler = SIG_IGN,
102 .sa_flags = SA_RESTART,
109 r = sigaction_many_ap(&sa, sig, ap);
115 /// UNNEEDED by elogind
117 int default_signals(int sig, ...) {
119 static const struct sigaction sa = {
120 .sa_handler = SIG_DFL,
121 .sa_flags = SA_RESTART,
128 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);