From: Roy Marples Date: Sat, 9 May 2015 10:09:34 +0000 (+0000) Subject: Remove dhcpcd specifics from eloop to make more portable. X-Git-Tag: v6.9.0~41 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8d3d5b8221d813e8c1de1ca74fbd200dccc76368;p=thirdparty%2Fdhcpcd.git Remove dhcpcd specifics from eloop to make more portable. --- diff --git a/dhcpcd.c b/dhcpcd.c index 2ffdac1d..7228e9d3 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -66,7 +66,7 @@ const char dhcpcd_copyright[] = "Copyright (c) 2006-2015 Roy Marples"; #include "script.h" #ifdef USE_SIGNALS -const int dhcpcd_handlesigs[] = { +const int dhcpcd_signals[] = { SIGTERM, SIGINT, SIGALRM, @@ -77,9 +77,16 @@ const int dhcpcd_handlesigs[] = { 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) static pid_t @@ -1116,21 +1123,18 @@ stop_all_interfaces(struct dhcpcd_ctx *ctx, int do_release) } #ifdef USE_SIGNALS -struct dhcpcd_siginfo dhcpcd_siginfo; #define sigmsg "received %s, %s" -void -dhcpcd_handle_signal(void *arg) +static void +handle_signal2(void *arg, int sig) { - struct dhcpcd_ctx *ctx; - struct dhcpcd_siginfo *si; + struct dhcpcd_ctx *ctx = arg; struct interface *ifp; - int do_release, exit_code;; + int do_release, exit_code; ctx = dhcpcd_ctx; - si = arg; do_release = 0; exit_code = EXIT_FAILURE; - switch (si->signo) { + switch (sig) { case SIGINT: logger(ctx, LOG_INFO, sigmsg, "SIGINT", "stopping"); break; @@ -1169,7 +1173,7 @@ dhcpcd_handle_signal(void *arg) logger(ctx, LOG_ERR, "received signal %d, " "but don't know what to do with it", - si->signo); + sig); return; } @@ -1179,6 +1183,14 @@ dhcpcd_handle_signal(void *arg) } #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) { @@ -1186,9 +1198,10 @@ 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.signo = sig; + dhcpcd_siginfo.ctx = dhcpcd_ctx; + dhcpcd_siginfo.sig = sig; eloop_timeout_add_now(dhcpcd_ctx->eloop, - dhcpcd_handle_signal, &dhcpcd_siginfo); + handle_signal1, &dhcpcd_siginfo); } #endif @@ -1211,8 +1224,8 @@ signal_init(sigset_t *oldset) sa.sa_flags = SA_SIGINFO; sigemptyset(&sa.sa_mask); - for (i = 0; dhcpcd_handlesigs[i]; i++) { - if (sigaction(dhcpcd_handlesigs[i], &sa, NULL) == -1) + for (i = 0; dhcpcd_signals[i]; i++) { + if (sigaction(dhcpcd_signals[i], &sa, NULL) == -1) return -1; } #endif @@ -1555,7 +1568,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); + ctx.eloop = eloop_init(&ctx, handle_signal2, dhcpcd_signals); if (ctx.eloop == NULL) { logger(&ctx, LOG_ERR, "%s: eloop_init: %m", __func__); goto exit_failure; @@ -1843,7 +1856,7 @@ main(int argc, char **argv) dhcpcd_prestartinterface, ifp); } - i = eloop_start(ctx.eloop); + i = eloop_start(ctx.eloop, &ctx.sigset); goto exit1; exit_success: diff --git a/dhcpcd.h b/dhcpcd.h index 8b34997c..a645522f 100644 --- a/dhcpcd.h +++ b/dhcpcd.h @@ -152,12 +152,7 @@ struct dhcpcd_ctx { }; #ifdef USE_SIGNALS -struct dhcpcd_siginfo { - int signo; -}; - -extern const int dhcpcd_handlesigs[]; -void dhcpcd_handle_signal(void *); +extern const int dhcpcd_signals[]; #endif int dhcpcd_oneup(struct dhcpcd_ctx *); diff --git a/eloop.c b/eloop.c index e479ac16..56ddeccb 100644 --- a/eloop.c +++ b/eloop.c @@ -32,12 +32,18 @@ #include #include #include +#include #include +/* config.h should define HAVE_KQUEUE, HAVE_EPOLL, etc */ #include "config.h" +#include "eloop.h" + +/* custom syslog wrapper for dhcpcd */ #include "common.h" #include "dhcpcd.h" -#include "eloop.h" +#define syslog(PRIO, FMT, ...) \ + logger((struct dhcpcd_ctx *)ctx->cb_ctx, PRIO, FMT, __VA_ARGS__) #if defined(HAVE_KQUEUE) #include @@ -188,7 +194,7 @@ eloop_event_add(struct eloop_ctx *ctx, int fd, return 0; err: - logger(ctx->ctx, LOG_ERR, "%s: %m", __func__); + syslog(LOG_ERR, "%s: %m", __func__); if (e) { ctx->events_len--; TAILQ_INSERT_TAIL(&ctx->free_events, e, next); @@ -285,7 +291,7 @@ eloop_q_timeout_add_tv(struct eloop_ctx *ctx, int queue, } else { t = malloc(sizeof(*t)); if (t == NULL) { - logger(ctx->ctx, LOG_ERR, "%s: %m", __func__); + syslog(LOG_ERR, "%s: %m", __func__); return -1; } } @@ -326,8 +332,7 @@ eloop_timeout_add_now(struct eloop_ctx *ctx, { if (ctx->timeout0 != NULL) { - logger(ctx->ctx, LOG_WARNING, - "%s: timeout0 already set", __func__); + syslog(LOG_WARNING, "%s: timeout0 already set", __func__); return eloop_q_timeout_add_sec(ctx, 0, 0, callback, arg); } @@ -405,7 +410,7 @@ eloop_requeue(struct eloop_ctx *ctx) return -1; #if defined (HAVE_KQUEUE) i = 0; - while (dhcpcd_handlesigs[i]) + while (ctx->signals[i] != 0) i++; TAILQ_FOREACH(e, &ctx->events, next) { i++; @@ -416,8 +421,8 @@ eloop_requeue(struct eloop_ctx *ctx) if ((ke = malloc(sizeof(*ke) * i)) == NULL) return -1; - for (i = 0; dhcpcd_handlesigs[i]; i++) - EV_SET(&ke[i], (uintptr_t)dhcpcd_handlesigs[i], + for (i = 0; ctx->signal[i] != 0; i++) + EV_SET(&ke[i], (uintptr_t)ctx->signals[i], EVFILT_SIGNAL, EV_ADD, 0, 0, UPTR(NULL)); TAILQ_FOREACH(e, &ctx->events, next) { @@ -454,7 +459,7 @@ eloop_requeue(struct eloop_ctx *ctx) #endif struct eloop_ctx * -eloop_init(struct dhcpcd_ctx *dctx) +eloop_init(void *ectx, void (*signal_cb)(void *, int), const int *signals) { struct eloop_ctx *ctx; struct timespec now; @@ -465,7 +470,8 @@ eloop_init(struct dhcpcd_ctx *dctx) ctx = calloc(1, sizeof(*ctx)); if (ctx) { - ctx->ctx = dctx; + ctx->cb_ctx = ectx; + ctx->signal_cb = signal_cb; TAILQ_INIT(&ctx->events); TAILQ_INIT(&ctx->free_events); TAILQ_INIT(&ctx->timeouts); @@ -474,6 +480,7 @@ eloop_init(struct dhcpcd_ctx *dctx) #if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL) ctx->poll_fd = -1; #endif + ctx->signals = signals; if (eloop_requeue(ctx) == -1) { free(ctx); return NULL; @@ -516,7 +523,7 @@ void eloop_free(struct eloop_ctx *ctx) } int -eloop_start(struct eloop_ctx *ctx) +eloop_start(struct eloop_ctx *ctx, sigset_t *signals) { int n; struct eloop_event *e; @@ -528,6 +535,7 @@ eloop_start(struct eloop_ctx *ctx) #endif #if defined(HAVE_KQUEUE) struct kevent ke; + UNUSED(signals); #elif defined(HAVE_EPOLL) struct epoll_event epe; #endif @@ -544,7 +552,7 @@ eloop_start(struct eloop_ctx *ctx) continue; } if ((t = TAILQ_FIRST(&ctx->timeouts))) { - get_monotonic(&now); + clock_gettime(CLOCK_MONOTONIC, &now); if (timespeccmp(&now, &t->when, >)) { TAILQ_REMOVE(&ctx->timeouts, t, next); t->callback(t->arg); @@ -558,7 +566,7 @@ eloop_start(struct eloop_ctx *ctx) tsp = NULL; if (tsp == NULL && ctx->events_len == 0) { - logger(ctx->ctx, LOG_ERR, "nothing to do"); + syslog(LOG_ERR, "%s: nothing to do", __func__); break; } @@ -578,15 +586,13 @@ eloop_start(struct eloop_ctx *ctx) n = kevent(ctx->poll_fd, NULL, 0, &ke, 1, tsp); #elif defined(HAVE_EPOLL) #ifdef USE_SIGNALS - n = epoll_pwait(ctx->poll_fd, &epe, 1, timeout, - &ctx->ctx->sigset); + n = epoll_pwait(ctx->poll_fd, &epe, 1, timeout, signals); #else n = epoll_wait(ctx->poll_fd, &epe, 1, timeout); #endif #else #ifdef USE_SIGNALS - n = pollts(ctx->fds, (nfds_t)ctx->events_len, tsp, - &ctx->ctx->sigset); + n = pollts(ctx->fds, (nfds_t)ctx->events_len, tsp, signals); #else n = poll(ctx->fds, (nfds_t)ctx->events_len, timeout); #endif @@ -594,7 +600,7 @@ eloop_start(struct eloop_ctx *ctx) if (n == -1) { if (errno == EINTR) continue; - logger(ctx->ctx, LOG_ERR, "poll: %m"); + syslog(LOG_ERR, "%s: poll: %m", __func__); break; } @@ -604,10 +610,7 @@ eloop_start(struct eloop_ctx *ctx) #if defined(HAVE_KQUEUE) if (n) { if (ke.filter == EVFILT_SIGNAL) { - struct dhcpcd_siginfo si; - - si.signo = (int)ke.ident; - dhcpcd_handle_signal(&si); + ctx->signal_cb(ctx->cb_ctx, (int)ke.ident); continue; } e = (struct eloop_event *)ke.udata; diff --git a/eloop.h b/eloop.h index 9bb670ca..08737887 100644 --- a/eloop.h +++ b/eloop.h @@ -61,7 +61,7 @@ struct eloop_timeout { }; struct eloop_ctx { - struct dhcpcd_ctx *ctx; + void *cb_ctx; size_t events_len; TAILQ_HEAD (event_head, eloop_event) events; @@ -72,6 +72,8 @@ struct eloop_ctx { void (*timeout0)(void *); void *timeout0_arg; + const int *signals; + void (*signal_cb)(void *, int); #if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL) int poll_fd; @@ -103,14 +105,14 @@ int eloop_q_timeout_add_tv(struct eloop_ctx *, int queue, 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(struct dhcpcd_ctx *); +struct eloop_ctx * eloop_init(void *, void (*)(void *, int), const int *); #if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL) int eloop_requeue(struct eloop_ctx *); #else -#define eloop_requeue(a) (0) +#define eloop_requeue(a, b) (0) #endif void eloop_free(struct eloop_ctx *); void eloop_exit(struct eloop_ctx *, int); -int eloop_start(struct eloop_ctx *); +int eloop_start(struct eloop_ctx *, sigset_t *); #endif diff --git a/script.c b/script.c index 918f700c..0991476a 100644 --- a/script.c +++ b/script.c @@ -107,8 +107,8 @@ exec_script(const struct dhcpcd_ctx *ctx, char *const *argv, char *const *env) flags = POSIX_SPAWN_SETSIGMASK | POSIX_SPAWN_SETSIGDEF; posix_spawnattr_setflags(&attr, flags); sigemptyset(&defsigs); - for (i = 0; dhcpcd_handlesigs[i]; i++) - sigaddset(&defsigs, dhcpcd_handlesigs[i]); + for (i = 0; dhcpcd_signals[i]; i++) + sigaddset(&defsigs, dhcpcd_signals[i]); posix_spawnattr_setsigdefault(&attr, &defsigs); posix_spawnattr_setsigmask(&attr, &ctx->sigset); #endif