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/>.
22 #include "parse-util.h"
23 #include "signal-util.h"
24 #include "string-table.h"
25 #include "string-util.h"
28 int reset_all_signal_handlers(void) {
29 static const struct sigaction sa = {
30 .sa_handler = SIG_DFL,
31 .sa_flags = SA_RESTART,
35 for (sig = 1; sig < _NSIG; sig++) {
37 /* These two cannot be caught... */
38 if (sig == SIGKILL || sig == SIGSTOP)
41 /* On Linux the first two RT signals are reserved by
42 * glibc, and sigaction() will return EINVAL for them. */
43 if ((sigaction(sig, &sa, NULL) < 0))
44 if (errno != EINVAL && r >= 0)
51 int reset_signal_mask(void) {
54 if (sigemptyset(&ss) < 0)
57 if (sigprocmask(SIG_SETMASK, &ss, NULL) < 0)
63 static int sigaction_many_ap(const struct sigaction *sa, int sig, va_list ap) {
66 /* negative signal ends the list. 0 signal is skipped. */
72 if (sigaction(sig, sa, NULL) < 0)
76 while ((sig = va_arg(ap, int)) >= 0) {
81 if (sigaction(sig, sa, NULL) < 0) {
90 #if 0 /// UNNEEDED by elogind
91 int sigaction_many(const struct sigaction *sa, ...) {
96 r = sigaction_many_ap(sa, 0, ap);
103 int ignore_signals(int sig, ...) {
105 static const struct sigaction sa = {
106 .sa_handler = SIG_IGN,
107 .sa_flags = SA_RESTART,
114 r = sigaction_many_ap(&sa, sig, ap);
120 #if 0 /// UNNEEDED by elogind
121 int default_signals(int sig, ...) {
123 static const struct sigaction sa = {
124 .sa_handler = SIG_DFL,
125 .sa_flags = SA_RESTART,
132 r = sigaction_many_ap(&sa, sig, ap);
139 static int sigset_add_many_ap(sigset_t *ss, va_list ap) {
144 while ((sig = va_arg(ap, int)) >= 0) {
149 if (sigaddset(ss, sig) < 0) {
158 int sigset_add_many(sigset_t *ss, ...) {
163 r = sigset_add_many_ap(ss, ap);
169 int sigprocmask_many(int how, sigset_t *old, ...) {
174 if (sigemptyset(&ss) < 0)
178 r = sigset_add_many_ap(&ss, ap);
184 if (sigprocmask(how, &ss, old) < 0)
190 static const char *const __signal_table[] = {
207 [SIGSTKFLT] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */
218 [SIGVTALRM] = "VTALRM",
220 [SIGWINCH] = "WINCH",
226 DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int);
228 const char *signal_to_string(int signo) {
229 static thread_local char buf[sizeof("RTMIN+")-1 + DECIMAL_STR_MAX(int) + 1];
232 name = __signal_to_string(signo);
236 if (signo >= SIGRTMIN && signo <= SIGRTMAX)
237 snprintf(buf, sizeof(buf), "RTMIN+%d", signo - SIGRTMIN);
239 snprintf(buf, sizeof(buf), "%d", signo);
244 int signal_from_string(const char *s) {
249 signo = __signal_from_string(s);
253 if (startswith(s, "RTMIN+")) {
257 if (safe_atou(s, &u) >= 0) {
258 signo = (int) u + offset;
259 if (signo > 0 && signo < _NSIG)
265 int signal_from_string_try_harder(const char *s) {
269 signo = signal_from_string(s);
271 if (startswith(s, "SIG"))
272 return signal_from_string(s+3);
277 #if 0 /// UNNEEDED by elogind
278 void nop_signal_handler(int sig) {