#include "macro.h"
#include "strv.h"
#include "log.h"
+#include "util.h"
Manager* manager_new(void) {
Manager *m;
if ((m->epoll_fd = epoll_create1(EPOLL_CLOEXEC)) < 0)
goto fail;
+ assert_se(reset_all_signal_handlers() == 0);
+
assert_se(sigemptyset(&mask) == 0);
assert_se(sigaddset(&mask, SIGCHLD) == 0);
+ assert_se(sigaddset(&mask, SIGINT) == 0);
+ assert_se(sigaddset(&mask, SIGTERM) == 0);
+ assert_se(sigaddset(&mask, SIGWINCH) == 0);
+ assert_se(sigaddset(&mask, SIGHUP) == 0);
assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
m->signal_watch.type = WATCH_SIGNAL_FD;
return 0;
}
-static int manager_process_signal_fd(Manager *m) {
+static int manager_process_signal_fd(Manager *m, bool *quit) {
ssize_t n;
struct signalfd_siginfo sfsi;
bool sigchld = false;
return -errno;
}
- if (sfsi.ssi_signo == SIGCHLD)
+ switch (sfsi.ssi_signo) {
+
+ case SIGCHLD:
sigchld = true;
+ break;
+
+ case SIGINT:
+ case SIGTERM:
+ *quit = true;
+ return 0;
+
+ default:
+ log_info("Got unhandled signal <%s>.", strsignal(sfsi.ssi_signo));
+ }
}
if (sigchld)
return 0;
}
-static int process_event(Manager *m, struct epoll_event *ev) {
+static int process_event(Manager *m, struct epoll_event *ev, bool *quit) {
int r;
Watch *w;
if (ev->events != POLLIN)
return -EINVAL;
- if ((r = manager_process_signal_fd(m)) < 0)
+ if ((r = manager_process_signal_fd(m, quit)) < 0)
return r;
break;
int manager_loop(Manager *m) {
int r;
+ bool quit = false;
assert(m);
for (;;) {
- struct epoll_event events[32];
- int n, i;
+ struct epoll_event event;
+ int n;
manager_dispatch_run_queue(m);
- if ((n = epoll_wait(m->epoll_fd, events, ELEMENTSOF(events), -1)) < 0) {
+ if ((n = epoll_wait(m->epoll_fd, &event, 1, -1)) < 0) {
if (errno == -EINTR)
continue;
return -errno;
}
- for (i = 0; i < n; i++)
- if ((r = process_event(m, events + i)) < 0)
- return r;
+ assert(n == 1);
+
+ if ((r = process_event(m, &event, &quit)) < 0)
+ return r;
+
+ if (quit)
+ return 0;
}
}