chiark / gitweb /
everywhere: port everything to sigprocmask_many() and friends
authorLennart Poettering <lennart@poettering.net>
Mon, 15 Jun 2015 18:13:23 +0000 (20:13 +0200)
committerSven Eden <yamakuzure@gmx.net>
Tue, 14 Mar 2017 09:03:02 +0000 (10:03 +0100)
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.

src/libelogind/sd-event/test-event.c
src/login/logind.c
src/shared/ask-password-api.c
src/shared/signal-util.c
src/shared/signal-util.h

index 94e98e0..408e167 100644 (file)
@@ -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);
index 6db99fc..a83d944 100644 (file)
@@ -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)
index ef3788b..3941605 100644 (file)
@@ -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);
 
index 9a2973b..d24730d 100644 (file)
 #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;
index ddf64cd..5e6eb50 100644 (file)
@@ -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_;