1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2015 Lennart Poettering
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
26 #include "parse-util.h"
27 #include "signal-util.h"
28 #include "stdio-util.h"
29 #include "string-table.h"
30 #include "string-util.h"
32 int reset_all_signal_handlers(void) {
33 static const struct sigaction sa = {
34 .sa_handler = SIG_DFL,
35 .sa_flags = SA_RESTART,
39 for (sig = 1; sig < _NSIG; sig++) {
41 /* These two cannot be caught... */
42 if (IN_SET(sig, SIGKILL, SIGSTOP))
45 /* On Linux the first two RT signals are reserved by
46 * glibc, and sigaction() will return EINVAL for them. */
47 if ((sigaction(sig, &sa, NULL) < 0))
48 if (errno != EINVAL && r >= 0)
55 int reset_signal_mask(void) {
58 if (sigemptyset(&ss) < 0)
61 if (sigprocmask(SIG_SETMASK, &ss, NULL) < 0)
67 static int sigaction_many_ap(const struct sigaction *sa, int sig, va_list ap) {
70 /* negative signal ends the list. 0 signal is skipped. */
76 if (sigaction(sig, sa, NULL) < 0)
80 while ((sig = va_arg(ap, int)) >= 0) {
85 if (sigaction(sig, sa, NULL) < 0) {
94 #if 0 /// UNNEEDED by elogind
95 int sigaction_many(const struct sigaction *sa, ...) {
100 r = sigaction_many_ap(sa, 0, ap);
107 int ignore_signals(int sig, ...) {
109 static const struct sigaction sa = {
110 .sa_handler = SIG_IGN,
111 .sa_flags = SA_RESTART,
118 r = sigaction_many_ap(&sa, sig, ap);
124 int default_signals(int sig, ...) {
126 static const struct sigaction sa = {
127 .sa_handler = SIG_DFL,
128 .sa_flags = SA_RESTART,
135 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[STRLEN("RTMIN+") + DECIMAL_STR_MAX(int) + 1];
234 name = __signal_to_string(signo);
238 if (signo >= SIGRTMIN && signo <= SIGRTMAX)
239 xsprintf(buf, "RTMIN+%d", signo - SIGRTMIN);
241 xsprintf(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 (SIGNAL_VALID(signo))
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 #if 0 /// UNNEEDED by elogind
280 void nop_signal_handler(int sig) {