From 9606d987722ee5b89bbfae230389d3385a3884b0 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Thu, 14 May 2020 17:49:44 +0200 Subject: Replace standard signal handling in initd with signalfd + epoll Signed-off-by: David Oberhollenzer --- initd/main.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 13 deletions(-) (limited to 'initd/main.c') diff --git a/initd/main.c b/initd/main.c index d92a823..9c4bf78 100644 --- a/initd/main.c +++ b/initd/main.c @@ -58,13 +58,17 @@ static void start_service(svc_run_data_t *rt) print_status(rt); } -static void handle_signal(int signo) +static void handle_signal(int fd) { + struct signalfd_siginfo info; svc_run_data_t *rt; int status; pid_t pid; - switch (signo) { + if (read(fd, &info, sizeof(info)) < (ssize_t)sizeof(info)) + return; + + switch (info.ssi_signo) { case SIGTERM: config_set_target(TGT_SHUTDOWN); break; @@ -96,20 +100,43 @@ static void handle_signal(int signo) int main(void) { + struct epoll_event ev; svc_run_data_t *rt; - struct sigaction act; + int ret, sfd, epfd; + sigset_t sigmask; + + cli(NULL); if (config_load()) return EXIT_FAILURE; - memset(&act, 0, sizeof(act)); - act.sa_handler = handle_signal; + epfd = epoll_create1(EPOLL_CLOEXEC); + if (epfd < 0) { + perror("epoll_create"); + return EXIT_FAILURE; + } - sigaction(SIGTERM, &act, NULL); - sigaction(SIGINT, &act, NULL); - sigaction(SIGHUP, &act, NULL); - sigaction(SIGUSR1, &act, NULL); - sigaction(SIGCHLD, &act, NULL); + sigemptyset(&sigmask); + sigaddset(&sigmask, SIGTERM); + sigaddset(&sigmask, SIGINT); + sigaddset(&sigmask, SIGHUP); + sigaddset(&sigmask, SIGUSR1); + sigaddset(&sigmask, SIGCHLD); + + sfd = signalfd(-1, &sigmask, SFD_CLOEXEC); + if (sfd < 0) { + perror("signalfd"); + return EXIT_FAILURE; + } + + memset(&ev, 0, sizeof(ev)); + ev.events = EPOLLIN; + ev.data.fd = sfd; + + if (epoll_ctl(epfd, EPOLL_CTL_ADD, sfd, &ev)) { + perror("adding signalfd to epoll"); + return EXIT_FAILURE; + } if (reboot(LINUX_REBOOT_CMD_CAD_OFF)) perror("cannot disable CTRL+ALT+DEL"); @@ -117,10 +144,22 @@ int main(void) for (;;) { rt = config_dequeue(); - if (rt == NULL) { - pause(); - } else { + if (rt != NULL) { start_service(rt); + continue; + } + + ret = epoll_wait(epfd, &ev, 1, -1); + if (ret == 0) + continue; + + if (ret < 0) { + perror("epoll wait"); + return EXIT_FAILURE; + } + + if (ev.data.fd == sfd) { + handle_signal(sfd); } } -- cgit v1.2.3