chiark / gitweb /
networkd: handle SIGINT and SIGTERM
[elogind.git] / src / network / networkd-manager.c
index f817d698c4cfec2ad0956886c82d8b70a0ee7ad6..c89adfba4f84373d536c5ee63d2adc39c0a73076 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;
@@ -52,7 +84,7 @@ int manager_new(Manager **ret) {
 
         sd_event_set_watchdog(m->event, true);
 
-        r = sd_rtnl_open(RTMGRP_LINK | RTMGRP_IPV4_IFADDR, &m->rtnl);
+        r = sd_rtnl_open(&m->rtnl, RTMGRP_LINK | RTMGRP_IPV4_IFADDR);
         if (r < 0)
                 return 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))
@@ -252,9 +290,10 @@ int manager_udev_listen(Manager *m) {
         }
 
         r = sd_event_add_io(m->event,
+                        &m->udev_event_source,
                         udev_monitor_get_fd(m->udev_monitor),
                         EPOLLIN, manager_dispatch_link_udev,
-                        m, &m->udev_event_source);
+                        m);
         if (r < 0)
                 return r;