]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Move signal handling into eloop with just the callback in dhcpcd.
authorRoy Marples <roy@marples.name>
Tue, 12 May 2015 14:14:32 +0000 (14:14 +0000)
committerRoy Marples <roy@marples.name>
Tue, 12 May 2015 14:14:32 +0000 (14:14 +0000)
This allows a cleaner platform agnostic signal setup in dhcpcd itself.

dhcpcd.c
eloop.c
eloop.h

index d4546cc05158dc6cd4f34b4a395f1effbdcbd5ef..82c09806448039f5faa75b01157a9af9d5fbb5dc 100644 (file)
--- a/dhcpcd.c
+++ b/dhcpcd.c
@@ -76,16 +76,6 @@ const int dhcpcd_signals[] = {
        SIGPIPE,
        0
 };
-
-#ifndef HAVE_KQUEUE
-struct dhcpcd_siginfo {
-       struct dhcpcd_ctx *ctx;
-       int sig;
-} dhcpcd_siginfo;
-
-/* Handling signals needs *some* context */
-static struct dhcpcd_ctx *dhcpcd_ctx;
-#endif
 #endif
 
 #if defined(USE_SIGNALS) || !defined(THERE_IS_NO_FORK)
@@ -1125,7 +1115,7 @@ stop_all_interfaces(struct dhcpcd_ctx *ctx, int do_release)
 #ifdef USE_SIGNALS
 #define sigmsg "received %s, %s"
 static void
-handle_signal2(void *arg, int sig)
+signal_cb(int sig, void *arg)
 {
        struct dhcpcd_ctx *ctx = arg;
        struct interface *ifp;
@@ -1180,56 +1170,6 @@ handle_signal2(void *arg, int sig)
                stop_all_interfaces(ctx, do_release);
        eloop_exit(ctx->eloop, exit_code);
 }
-
-#ifndef HAVE_KQUEUE
-static void
-handle_signal1(void *arg)
-{
-       struct dhcpcd_siginfo *si = arg;
-
-       handle_signal2(si->ctx, si->sig);
-}
-
-static void
-handle_signal(int sig, __unused siginfo_t *siginfo, __unused void *context)
-{
-
-       /* So that we can operate safely under a signal we instruct
-        * eloop to pass a copy of the siginfo structure to handle_signal1
-        * as the very first thing to do. */
-       dhcpcd_siginfo.ctx = dhcpcd_ctx;
-       dhcpcd_siginfo.sig = sig;
-       eloop_timeout_add_now(dhcpcd_ctx->eloop,
-           handle_signal1, &dhcpcd_siginfo);
-}
-#endif
-
-static int
-signal_init(sigset_t *oldset)
-{
-       sigset_t newset;
-#ifndef HAVE_KQUEUE
-       int i;
-       struct sigaction sa;
-#endif
-
-       sigfillset(&newset);
-       if (sigprocmask(SIG_SETMASK, &newset, oldset) == -1)
-               return -1;
-
-#ifndef HAVE_KQUEUE
-       memset(&sa, 0, sizeof(sa));
-       sa.sa_sigaction = handle_signal;
-       sa.sa_flags = SA_SIGINFO;
-       sigemptyset(&sa.sa_mask);
-
-       for (i = 0; dhcpcd_signals[i]; i++) {
-               if (sigaction(dhcpcd_signals[i], &sa, NULL) == -1)
-                       return -1;
-       }
-#endif
-       return 0;
-}
 #endif
 
 static void
@@ -1569,8 +1509,7 @@ main(int argc, char **argv)
 
        /* Freeing allocated addresses from dumping leases can trigger
         * eloop removals as well, so init here. */
-       ctx.eloop = eloop_init(&ctx, handle_signal2, dhcpcd_signals);
-       if (ctx.eloop == NULL) {
+       if ((ctx.eloop = eloop_new()) == NULL) {
                logger(&ctx, LOG_ERR, "%s: eloop_init: %m", __func__);
                goto exit_failure;
        }
@@ -1758,9 +1697,15 @@ main(int argc, char **argv)
        logger(&ctx, LOG_DEBUG, PACKAGE "-" VERSION " starting");
        ctx.options |= DHCPCD_STARTED;
 #ifdef USE_SIGNALS
+       if (eloop_signal_set_cb(ctx.eloop, dhcpcd_signals,
+           signal_cb, &ctx) == -1)
+       {
+               logger(&ctx, LOG_ERR, "eloop_signal_mask: %m");
+               goto exit_failure;
+       }
        /* Save signal mask, block and redirect signals to our handler */
-       if (signal_init(&ctx.sigset) == -1) {
-               logger(&ctx, LOG_ERR, "signal_setup: %m");
+       if (eloop_signal_mask(ctx.eloop, &ctx.sigset) == -1) {
+               logger(&ctx, LOG_ERR, "eloop_signal_mask: %m");
                goto exit_failure;
        }
 #endif
diff --git a/eloop.c b/eloop.c
index 001a92fe4d25706e70d95e016b8435f2032953f6..7058f5b3c4ed0ba0bd38e30f26e620ac22179ee2 100644 (file)
--- a/eloop.c
+++ b/eloop.c
@@ -27,6 +27,7 @@
 
 #include <sys/time.h>
 
+#include <assert.h>
 #include <errno.h>
 #include <limits.h>
 #include <signal.h>
@@ -43,7 +44,7 @@
 #include "common.h"
 #include "dhcpcd.h"
 #define syslog(PRIO, FMT, ...) \
-       logger((struct dhcpcd_ctx *)ctx->cb_ctx, PRIO, FMT, __VA_ARGS__)
+       logger((struct dhcpcd_ctx *)ctx->signal_cb_ctx, PRIO, FMT, __VA_ARGS__)
 
 #if defined(HAVE_KQUEUE)
 #include <sys/event.h>
@@ -326,7 +327,7 @@ eloop_q_timeout_add_sec(struct eloop_ctx *ctx, int queue, time_t when,
 }
 
 #if !defined(HAVE_KQUEUE)
-int
+static int
 eloop_timeout_add_now(struct eloop_ctx *ctx,
     void (*callback)(void *), void *arg)
 {
@@ -458,8 +459,78 @@ eloop_requeue(struct eloop_ctx *ctx)
 }
 #endif
 
+int
+eloop_signal_set_cb(struct eloop_ctx *ctx,
+    const int *signals, void (*signal_cb)(int, void *), void *signal_cb_ctx)
+{
+
+       assert(ctx);
+       ctx->signals = signals;
+       ctx->signal_cb = signal_cb;
+       ctx->signal_cb_ctx = signal_cb_ctx;
+       return eloop_requeue(ctx);
+}
+
+#ifndef HAVE_KQUEUE
+struct eloop_siginfo {
+       int sig;
+       struct eloop_ctx *ctx;
+};
+static struct eloop_siginfo eloop_siginfo;
+static struct eloop_ctx *eloop_ctx;
+
+static void
+eloop_signal1(void *arg)
+{
+       struct eloop_siginfo *si = arg;
+
+       si->ctx->signal_cb(si->cig, si->ctx->signal_cb_arg);
+}
+
+static void
+eloop_signal3(int sig, __unused siginfo_t *siginfo, __unused void *arg)
+{
+
+       /* So that we can operate safely under a signal we instruct
+        * eloop to pass a copy of the siginfo structure to handle_signal1
+        * as the very first thing to do. */
+       eloop_siginfo.sig = sig;
+       eloop_siginfo.ctx = eloop_ctx;
+       eloop_timeout_add_now(eloop_ctx, eloop_signal1, &eloop_siginfo);
+}
+#endif
+
+int
+eloop_signal_mask(struct eloop_ctx *ctx, sigset_t *oldset)
+{
+       sigset_t newset;
+#ifndef HAVE_KQUEUE
+       int i;
+       struct sigaction sa;
+#endif
+
+       sigfillset(&newset);
+       if (sigprocmask(SIG_SETMASK, &newset, oldset) == -1)
+               return -1;
+
+#ifdef HAVE_KQUEUE
+       UNUSED(ctx);
+#else
+       memset(&sa, 0, sizeof(sa));
+       sa.sa_sigaction = eloop_signal3;
+       sa.sa_flags = SA_SIGINFO;
+       sigemptyset(&sa.sa_mask);
+
+       for (i = 0; ctx->signals[i]; i++) {
+               if (sigaction(ctx->signals[i], &sa, NULL) == -1)
+                       return -1;
+       }
+#endif
+       return 0;
+}
+
 struct eloop_ctx *
-eloop_init(void *ectx, void (*signal_cb)(void *, int), const int *signals)
+eloop_new(void)
 {
        struct eloop_ctx *ctx;
        struct timespec now;
@@ -470,8 +541,6 @@ eloop_init(void *ectx, void (*signal_cb)(void *, int), const int *signals)
 
        ctx = calloc(1, sizeof(*ctx));
        if (ctx) {
-               ctx->cb_ctx = ectx;
-               ctx->signal_cb = signal_cb;
                TAILQ_INIT(&ctx->events);
                TAILQ_INIT(&ctx->free_events);
                TAILQ_INIT(&ctx->timeouts);
@@ -480,11 +549,6 @@ eloop_init(void *ectx, void (*signal_cb)(void *, int), const int *signals)
 #if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
                ctx->poll_fd = -1;
 #endif
-               ctx->signals = signals;
-               if (eloop_requeue(ctx) == -1) {
-                       free(ctx);
-                       return NULL;
-               }
        }
 
        return ctx;
@@ -610,7 +674,8 @@ eloop_start(struct eloop_ctx *ctx, sigset_t *signals)
 #if defined(HAVE_KQUEUE)
                if (n) {
                        if (ke.filter == EVFILT_SIGNAL) {
-                               ctx->signal_cb(ctx->cb_ctx, (int)ke.ident);
+                               ctx->signal_cb((int)ke.ident,
+                                   ctx->signal_cb_ctx);
                                continue;
                        }
                        e = (struct eloop_event *)ke.udata;
diff --git a/eloop.h b/eloop.h
index 0873788743744134d589bb482f8d5ae5953da34b..0969f7765faf3023d215eba267645a63690bdc44 100644 (file)
--- a/eloop.h
+++ b/eloop.h
@@ -61,8 +61,6 @@ struct eloop_timeout {
 };
 
 struct eloop_ctx {
-       void *cb_ctx;
-
        size_t events_len;
        TAILQ_HEAD (event_head, eloop_event) events;
        struct event_head free_events;
@@ -73,7 +71,8 @@ struct eloop_ctx {
        void (*timeout0)(void *);
        void *timeout0_arg;
        const int *signals;
-       void (*signal_cb)(void *, int);
+       void (*signal_cb)(int, void *);
+       void *signal_cb_ctx;
 
 #if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
        int poll_fd;
@@ -86,26 +85,29 @@ struct eloop_ctx {
        int exitcode;
 };
 
+int eloop_event_add(struct eloop_ctx *, int,
+    void (*)(void *), void *,
+    void (*)(void *), void *);
+void eloop_event_delete(struct eloop_ctx *, int, int);
+
+
 #define eloop_timeout_add_tv(a, b, c, d) \
     eloop_q_timeout_add_tv(a, ELOOP_QUEUE, b, c, d)
 #define eloop_timeout_add_sec(a, b, c, d) \
     eloop_q_timeout_add_sec(a, ELOOP_QUEUE, b, c, d)
 #define eloop_timeout_delete(a, b, c) \
     eloop_q_timeout_delete(a, ELOOP_QUEUE, b, c)
-
-int eloop_event_add(struct eloop_ctx *, int,
-    void (*)(void *), void *,
-    void (*)(void *), void *);
-void eloop_event_delete(struct eloop_ctx *, int, int);
 int eloop_q_timeout_add_sec(struct eloop_ctx *, int queue,
     time_t, void (*)(void *), void *);
 int eloop_q_timeout_add_tv(struct eloop_ctx *, int queue,
     const struct timespec *, void (*)(void *), void *);
-#if !defined(HAVE_KQUEUE)
-int eloop_timeout_add_now(struct eloop_ctx *, void (*)(void *), void *);
-#endif
 void eloop_q_timeout_delete(struct eloop_ctx *, int, void (*)(void *), void *);
-struct eloop_ctx * eloop_init(void *, void (*)(void *, int), const int *);
+
+int eloop_signal_set_cb(struct eloop_ctx *, const int *,
+    void (*)(int, void *), void *);
+int eloop_signal_mask(struct eloop_ctx *ctx, sigset_t *oldset);
+
+struct eloop_ctx * eloop_new(void);
 #if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
 int eloop_requeue(struct eloop_ctx *);
 #else