chiark / gitweb /
networkd: handle SIGINT and SIGTERM
authorTom Gundersen <teg@jklm.no>
Sat, 22 Feb 2014 19:19:49 +0000 (20:19 +0100)
committerTom Gundersen <teg@jklm.no>
Sat, 22 Feb 2014 20:24:36 +0000 (21:24 +0100)
src/network/networkd-link.c
src/network/networkd-manager.c
src/network/networkd.h
src/network/test-network.c

index e2d61ae..1f495b3 100644 (file)
@@ -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);
 
index 55e5caf..c89adfb 100644 (file)
@@ -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))
index fb09764..8307bb5 100644 (file)
@@ -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;
index 46afeec..9c372c7 100644 (file)
 
 #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);