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 /// UNNEEDED by elogind
92 int sigaction_many(const struct sigaction *sa, ...) {
97 r = sigaction_many_ap(sa, 0, ap);
104 int ignore_signals(int sig, ...) {
106 static const struct sigaction sa = {
107 .sa_handler = SIG_IGN,
108 .sa_flags = SA_RESTART,
115 r = sigaction_many_ap(&sa, sig, ap);
121 /// UNNEEDED by elogind
123 int default_signals(int sig, ...) {
125 static const struct sigaction sa = {
126 .sa_handler = SIG_DFL,
127 .sa_flags = SA_RESTART,
134 r = sigaction_many_ap(&sa, sig, ap);
141 static int sigset_add_many_ap(sigset_t *ss, va_list ap) {
146 while ((sig = va_arg(ap, int)) >= 0) {
151 if (sigaddset(ss, sig) < 0) {
160 int sigset_add_many(sigset_t *ss, ...) {
165 r = sigset_add_many_ap(ss, ap);
171 int sigprocmask_many(int how, sigset_t *old, ...) {
176 if (sigemptyset(&ss) < 0)
180 r = sigset_add_many_ap(&ss, ap);
186 if (sigprocmask(how, &ss, old) < 0)
192 static const char *const __signal_table[] = {
209 [SIGSTKFLT] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */
220 [SIGVTALRM] = "VTALRM",
222 [SIGWINCH] = "WINCH",
228 DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int);
230 const char *signal_to_string(int signo) {
231 static thread_local char buf[sizeof("RTMIN+")-1 + DECIMAL_STR_MAX(int) + 1];
234 name = __signal_to_string(signo);
238 if (signo >= SIGRTMIN && signo <= SIGRTMAX)
239 snprintf(buf, sizeof(buf), "RTMIN+%d", signo - SIGRTMIN);
241 snprintf(buf, sizeof(buf), "%d", signo);
246 int signal_from_string(const char *s) {
251 signo = __signal_from_string(s);
255 if (startswith(s, "RTMIN+")) {
259 if (safe_atou(s, &u) >= 0) {
260 signo = (int) u + offset;
261 if (signo > 0 && signo < _NSIG)
267 int signal_from_string_try_harder(const char *s) {
271 signo = signal_from_string(s);
273 if (startswith(s, "SIG"))
274 return signal_from_string(s+3);
279 /// UNNEEDED by elogind
281 void nop_signal_handler(int sig) {