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 int default_signals(int sig, ...) {
117 static const struct sigaction sa = {
118 .sa_handler = SIG_DFL,
119 .sa_flags = SA_RESTART,
126 r = sigaction_many_ap(&sa, sig, ap);
132 static int sigset_add_many_ap(sigset_t *ss, va_list ap) {
137 while ((sig = va_arg(ap, int)) >= 0) {
142 if (sigaddset(ss, sig) < 0) {
151 int sigset_add_many(sigset_t *ss, ...) {
156 r = sigset_add_many_ap(ss, ap);
162 int sigprocmask_many(int how, sigset_t *old, ...) {
167 if (sigemptyset(&ss) < 0)
171 r = sigset_add_many_ap(&ss, ap);
177 if (sigprocmask(how, &ss, old) < 0)
183 static const char *const __signal_table[] = {
200 [SIGSTKFLT] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */
211 [SIGVTALRM] = "VTALRM",
213 [SIGWINCH] = "WINCH",
219 DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int);
221 const char *signal_to_string(int signo) {
222 static thread_local char buf[sizeof("RTMIN+")-1 + DECIMAL_STR_MAX(int) + 1];
225 name = __signal_to_string(signo);
229 if (signo >= SIGRTMIN && signo <= SIGRTMAX)
230 snprintf(buf, sizeof(buf), "RTMIN+%d", signo - SIGRTMIN);
232 snprintf(buf, sizeof(buf), "%d", signo);
237 int signal_from_string(const char *s) {
242 signo = __signal_from_string(s);
246 if (startswith(s, "RTMIN+")) {
250 if (safe_atou(s, &u) >= 0) {
251 signo = (int) u + offset;
252 if (signo > 0 && signo < _NSIG)
258 int signal_from_string_try_harder(const char *s) {
262 signo = signal_from_string(s);
264 if (startswith(s, "SIG"))
265 return signal_from_string(s+3);