mirror of
https://github.com/rsmarples/dhcpcd.git
synced 2024-11-28 04:25:19 +08:00
Move signal handling into eloop with just the callback in dhcpcd.
This allows a cleaner platform agnostic signal setup in dhcpcd itself.
This commit is contained in:
parent
b3f1735bbf
commit
d22c40d379
75
dhcpcd.c
75
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
|
||||
|
87
eloop.c
87
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;
|
||||
|
26
eloop.h
26
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
|
||||
|
Loading…
Reference in New Issue
Block a user