From: Tom Gundersen Date: Sat, 22 Feb 2014 19:19:49 +0000 (+0100) Subject: networkd: handle SIGINT and SIGTERM X-Git-Tag: v210~45 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=0c2f9b84698b25e6065b9febd21486669a13870f networkd: handle SIGINT and SIGTERM --- diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index e2d61ae49..1f495b38b 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -35,6 +35,8 @@ int link_new(Manager *manager, struct udev_device *device, Link **ret) { const char *ifname; int r; + assert(manager); + assert(manager->links); assert(device); assert(ret); diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 55e5cafd0..c89adfba4 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -38,6 +38,38 @@ const char* const network_dirs[] = { #endif NULL}; +static int dispatch_sigterm(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) { + Manager *m = userdata; + + assert(m); + + log_received_signal(LOG_INFO, si); + + sd_event_exit(m->event, 0); + return 0; +} + +static int setup_signals(Manager *m) { + sigset_t mask; + int r; + + assert(m); + + assert_se(sigemptyset(&mask) == 0); + sigset_add_many(&mask, SIGINT, SIGTERM, -1); + assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0); + + r = sd_event_add_signal(m->event, &m->sigterm_event_source, SIGTERM, dispatch_sigterm, m); + if (r < 0) + return r; + + r = sd_event_add_signal(m->event, &m->sigint_event_source, SIGINT, dispatch_sigterm, m); + if (r < 0) + return r; + + return 0; +} + int manager_new(Manager **ret) { _cleanup_manager_free_ Manager *m = NULL; int r; @@ -60,6 +92,10 @@ int manager_new(Manager **ret) { if (r < 0 && r != -ENOENT) /* TODO: drop when we can rely on kdbus */ return r; + r = setup_signals(m); + if (r < 0) + return r; + m->udev = udev_new(); if (!m->udev) return -ENOMEM; @@ -105,6 +141,8 @@ void manager_free(Manager *m) { udev_unref(m->udev); sd_bus_unref(m->bus); sd_event_source_unref(m->udev_event_source); + sd_event_source_unref(m->sigterm_event_source); + sd_event_source_unref(m->sigint_event_source); sd_event_unref(m->event); while ((network = m->networks)) diff --git a/src/network/networkd.h b/src/network/networkd.h index fb0976491..8307bb5b1 100644 --- a/src/network/networkd.h +++ b/src/network/networkd.h @@ -201,6 +201,8 @@ struct Manager { struct udev *udev; struct udev_monitor *udev_monitor; sd_event_source *udev_event_source; + sd_event_source *sigterm_event_source; + sd_event_source *sigint_event_source; Hashmap *links; Hashmap *netdevs; diff --git a/src/network/test-network.c b/src/network/test-network.c index 46afeec92..9c372c779 100644 --- a/src/network/test-network.c +++ b/src/network/test-network.c @@ -21,12 +21,9 @@ #include "networkd.h" -static void test_link(struct udev_device *loopback) { - _cleanup_manager_free_ Manager *manager = NULL; +static void test_link(Manager *manager, struct udev_device *loopback) { Link *link = NULL; - manager_new(&manager); - assert_se(link_new(manager, loopback, &link) >= 0); assert_se(link); } @@ -69,7 +66,7 @@ int main(void) { test_network_get(manager, loopback); - test_link(loopback); + test_link(manager, loopback); assert_se(manager_udev_listen(manager) >= 0); assert_se(manager_udev_enumerate_links(manager) >= 0);