From: Lennart Poettering Date: Mon, 15 Jun 2015 18:13:23 +0000 (+0200) Subject: everywhere: port everything to sigprocmask_many() and friends X-Git-Tag: v226.4~1^2~285 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=d896ac2d2fbce41a0b11a0618a685adeaf18b8fe everywhere: port everything to sigprocmask_many() and friends This ports a lot of manual code over to sigprocmask_many() and friends. Also, we now consistly check for sigprocmask() failures with assert_se(), since the call cannot realistically fail unless there's a programming error. Also encloses a few sd_event_add_signal() calls with (void) when we ignore the return values for it knowingly. --- diff --git a/src/libelogind/sd-event/test-event.c b/src/libelogind/sd-event/test-event.c index 94e98e007..408e1679a 100644 --- a/src/libelogind/sd-event/test-event.c +++ b/src/libelogind/sd-event/test-event.c @@ -79,7 +79,6 @@ static int child_handler(sd_event_source *s, const siginfo_t *si, void *userdata static int signal_handler(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) { sd_event_source *p = NULL; - sigset_t ss; pid_t pid; assert_se(s); @@ -89,9 +88,7 @@ static int signal_handler(sd_event_source *s, const struct signalfd_siginfo *si, assert_se(userdata == INT_TO_PTR('e')); - assert_se(sigemptyset(&ss) >= 0); - assert_se(sigaddset(&ss, SIGCHLD) >= 0); - assert_se(sigprocmask(SIG_BLOCK, &ss, NULL) >= 0); + assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD, -1) >= 0); pid = fork(); assert_se(pid >= 0); @@ -109,7 +106,6 @@ static int signal_handler(sd_event_source *s, const struct signalfd_siginfo *si, static int defer_handler(sd_event_source *s, void *userdata) { sd_event_source *p = NULL; - sigset_t ss; assert_se(s); @@ -117,9 +113,8 @@ static int defer_handler(sd_event_source *s, void *userdata) { assert_se(userdata == INT_TO_PTR('d')); - assert_se(sigemptyset(&ss) >= 0); - assert_se(sigaddset(&ss, SIGUSR1) >= 0); - assert_se(sigprocmask(SIG_BLOCK, &ss, NULL) >= 0); + assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGUSR1, -1) >= 0); + assert_se(sd_event_add_signal(sd_event_source_get_event(s), &p, SIGUSR1, signal_handler, INT_TO_PTR('e')) >= 0); assert_se(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT) >= 0); raise(SIGUSR1); @@ -209,7 +204,7 @@ int main(int argc, char *argv[]) { assert_se(sd_event_source_set_prepare(z, prepare_handler) >= 0); /* Test for floating event sources */ - assert_se(sigprocmask_many(SIG_BLOCK, SIGRTMIN+1, -1) == 0); + assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGRTMIN+1, -1) >= 0); assert_se(sd_event_add_signal(e, NULL, SIGRTMIN+1, NULL, NULL) >= 0); assert_se(write(a[1], &ch, 1) >= 0); diff --git a/src/login/logind.c b/src/login/logind.c index 6db99fc5e..a83d9443d 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -787,13 +787,8 @@ static int manager_connect_console(Manager *m) { return -EINVAL; } - r = ignore_signals(SIGRTMIN + 1, -1); - if (r < 0) - return log_error_errno(r, "Cannot ignore SIGRTMIN + 1: %m"); - - r = sigprocmask_many(SIG_BLOCK, SIGRTMIN, -1); - if (r < 0) - return log_error_errno(r, "Cannot block SIGRTMIN: %m"); + assert_se(ignore_signals(SIGRTMIN + 1, -1) >= 0); + assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGRTMIN, -1) >= 0); r = sd_event_add_signal(m->event, NULL, SIGRTMIN, manager_vt_switch, m); if (r < 0) diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c index ef3788be6..3941605ce 100644 --- a/src/shared/ask-password-api.c +++ b/src/shared/ask-password-api.c @@ -323,9 +323,9 @@ int ask_password_agent( assert(_passphrases); - assert_se(sigemptyset(&mask) == 0); - sigset_add_many(&mask, SIGINT, SIGTERM, -1); - assert_se(sigprocmask(SIG_BLOCK, &mask, &oldmask) == 0); + assert_se(sigemptyset(&mask) >= 0); + assert_se(sigset_add_many(&mask, SIGINT, SIGTERM, -1) >= 0); + assert_se(sigprocmask(SIG_BLOCK, &mask, &oldmask) >= 0); mkdir_p_label("/run/systemd/ask-password", 0755); diff --git a/src/shared/signal-util.c b/src/shared/signal-util.c index 9a2973b6f..d24730d43 100644 --- a/src/shared/signal-util.c +++ b/src/shared/signal-util.c @@ -23,13 +23,13 @@ #include "signal-util.h" int reset_all_signal_handlers(void) { + static const struct sigaction sa = { + .sa_handler = SIG_DFL, + .sa_flags = SA_RESTART, + }; int sig, r = 0; for (sig = 1; sig < _NSIG; sig++) { - static const struct sigaction sa = { - .sa_handler = SIG_DFL, - .sa_flags = SA_RESTART, - }; /* These two cannot be caught... */ if (sig == SIGKILL || sig == SIGSTOP) @@ -38,7 +38,7 @@ int reset_all_signal_handlers(void) { /* On Linux the first two RT signals are reserved by * glibc, and sigaction() will return EINVAL for them. */ if ((sigaction(sig, &sa, NULL) < 0)) - if (errno != EINVAL && r == 0) + if (errno != EINVAL && r >= 0) r = -errno; } @@ -57,84 +57,124 @@ int reset_signal_mask(void) { return 0; } +static int sigaction_many_ap(const struct sigaction *sa, int sig, va_list ap) { + int r = 0; + + /* negative signal ends the list. 0 signal is skipped. */ + + if (sig < 0) + return 0; + + if (sig > 0) { + if (sigaction(sig, sa, NULL) < 0) + r = -errno; + } + + while ((sig = va_arg(ap, int)) >= 0) { + + if (sig == 0) + continue; + + if (sigaction(sig, sa, NULL) < 0) { + if (r >= 0) + r = -errno; + } + } + + return r; +} + int sigaction_many(const struct sigaction *sa, ...) { va_list ap; - int r = 0, sig; + int r; va_start(ap, sa); - while ((sig = va_arg(ap, int)) > 0) - if (sigaction(sig, sa, NULL) < 0) - r = -errno; + r = sigaction_many_ap(sa, 0, ap); va_end(ap); return r; } int ignore_signals(int sig, ...) { + static const struct sigaction sa = { .sa_handler = SIG_IGN, .sa_flags = SA_RESTART, }; - va_list ap; - int r = 0; - if (sigaction(sig, &sa, NULL) < 0) - r = -errno; + va_list ap; + int r; va_start(ap, sig); - while ((sig = va_arg(ap, int)) > 0) - if (sigaction(sig, &sa, NULL) < 0) - r = -errno; + r = sigaction_many_ap(&sa, sig, ap); va_end(ap); return r; } int default_signals(int sig, ...) { + static const struct sigaction sa = { .sa_handler = SIG_DFL, .sa_flags = SA_RESTART, }; - va_list ap; - int r = 0; - if (sigaction(sig, &sa, NULL) < 0) - r = -errno; + va_list ap; + int r; va_start(ap, sig); - while ((sig = va_arg(ap, int)) > 0) - if (sigaction(sig, &sa, NULL) < 0) - r = -errno; + r = sigaction_many_ap(&sa, sig, ap); va_end(ap); return r; } -void sigset_add_many(sigset_t *ss, ...) { - va_list ap; - int sig; +static int sigset_add_many_ap(sigset_t *ss, va_list ap) { + int sig, r = 0; assert(ss); + while ((sig = va_arg(ap, int)) >= 0) { + + if (sig == 0) + continue; + + if (sigaddset(ss, sig) < 0) { + if (r >= 0) + r = -errno; + } + } + + return r; +} + +int sigset_add_many(sigset_t *ss, ...) { + va_list ap; + int r; + va_start(ap, ss); - while ((sig = va_arg(ap, int)) > 0) - assert_se(sigaddset(ss, sig) == 0); + r = sigset_add_many_ap(ss, ap); va_end(ap); + + return r; } -int sigprocmask_many(int how, ...) { +int sigprocmask_many(int how, sigset_t *old, ...) { va_list ap; sigset_t ss; - int sig; + int r; - assert_se(sigemptyset(&ss) == 0); + if (sigemptyset(&ss) < 0) + return -errno; va_start(ap, how); - while ((sig = va_arg(ap, int)) > 0) - assert_se(sigaddset(&ss, sig) == 0); + r = sigset_add_many_ap(&ss, ap); va_end(ap); - if (sigprocmask(how, &ss, NULL) < 0) + if (r < 0) + return r; + + if (sigprocmask(how, &ss, old) < 0) return -errno; return 0; diff --git a/src/shared/signal-util.h b/src/shared/signal-util.h index ddf64cda7..5e6eb50b0 100644 --- a/src/shared/signal-util.h +++ b/src/shared/signal-util.h @@ -32,8 +32,8 @@ int ignore_signals(int sig, ...); int default_signals(int sig, ...); int sigaction_many(const struct sigaction *sa, ...); -void sigset_add_many(sigset_t *ss, ...); -int sigprocmask_many(int how, ...); +int sigset_add_many(sigset_t *ss, ...); +int sigprocmask_many(int how, sigset_t *old, ...); const char *signal_to_string(int i) _const_; int signal_from_string(const char *s) _pure_;