From 2cb64e48fcd664067f4bd87e8f46fad694c3c979 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Sun, 15 Apr 2018 13:21:34 +0200 Subject: [PATCH] Move initd signal setup to platform specific file Signed-off-by: David Oberhollenzer --- initd/Makemodule.am | 2 +- initd/init.h | 25 ++++++++++++++++++++++ initd/main.c | 20 +++-------------- initd/runlst.c | 4 +--- initd/signal_linux.c | 51 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 81 insertions(+), 21 deletions(-) create mode 100644 initd/signal_linux.c diff --git a/initd/Makemodule.am b/initd/Makemodule.am index 752978b..67515cc 100644 --- a/initd/Makemodule.am +++ b/initd/Makemodule.am @@ -1,4 +1,4 @@ -init_SOURCES = initd/main.c initd/runlst.c initd/init.h +init_SOURCES = initd/main.c initd/runlst.c initd/init.h initd/signal_linux.c init_SOURCES += initd/status.c initd/mksock.c initd/svclist.c initd/env.c init_CPPFLAGS = $(AM_CPPFLAGS) init_CFLAGS = $(AM_CFLAGS) diff --git a/initd/init.h b/initd/init.h index a43b3f1..3510073 100644 --- a/initd/init.h +++ b/initd/init.h @@ -19,7 +19,9 @@ #define INIT_H #include +#include #include +#include #include "service.h" #include "telinit.h" @@ -117,5 +119,28 @@ service_t *svclist_remove(pid_t pid); */ int initenv(void); +/********** signal_.c **********/ + +/* + Setup signal handling. Returns -1 on error, a file descriptor on + success. + + The returned file descriptor can be polled and becomes readable + when a signal arrives. Reading from it returns a signalfd_siginfo + structure. + + The returned file descriptor has the close on exec flag set. + + The kernel is also told to send us SIGINT signals if a user presses + the local equivalent of CTRL+ALT+DEL. +*/ +int sigsetup(void); + +/* + Undo everything that sigsetup() changed about signal handling and + restore the default. +*/ +void sigreset(void); + #endif /* INIT_H */ diff --git a/initd/main.c b/initd/main.c index 192a49a..05f9271 100644 --- a/initd/main.c +++ b/initd/main.c @@ -25,8 +25,6 @@ #include #include -#include - #include "init.h" static service_list_t cfg; @@ -189,32 +187,20 @@ int main(void) { int ti_sock = -1, sfd, ret, count; struct pollfd pfd[2]; - sigset_t mask; if (getpid() != 1) { fputs("init does not have pid 1, terminating!\n", stderr); return EXIT_FAILURE; } - if (reboot(LINUX_REBOOT_CMD_CAD_OFF)) - perror("cannot disable CTRL+ALT+DEL"); - if (svcscan(SVCDIR, &cfg)) { fputs("Error reading service list from " SVCDIR "\n" "Trying to continue anyway\n", stderr); } - sigfillset(&mask); - if (sigprocmask(SIG_SETMASK, &mask, NULL) == -1) { - perror("sigprocmask"); - return EXIT_FAILURE; - } - - sfd = signalfd(-1, &mask, SFD_CLOEXEC); - if (sfd == -1) { - perror("signalfd"); - return EXIT_FAILURE; - } + sfd = sigsetup(); + if (sfd < 0) + return -1; memset(pfd, 0, sizeof(pfd)); pfd[0].fd = sfd; diff --git a/initd/runlst.c b/initd/runlst.c index d1311a4..83823f9 100644 --- a/initd/runlst.c +++ b/initd/runlst.c @@ -26,11 +26,9 @@ static int child_setup(const char *ctty) { - sigset_t mask; int fd; - sigemptyset(&mask); - sigprocmask(SIG_SETMASK, &mask, NULL); + sigreset(); if (ctty != NULL) { fd = open(ctty, O_RDWR); diff --git a/initd/signal_linux.c b/initd/signal_linux.c new file mode 100644 index 0000000..aed049b --- /dev/null +++ b/initd/signal_linux.c @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * Copyright (C) 2018 - David Oberhollenzer + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include + +#include "init.h" + +int sigsetup(void) +{ + sigset_t mask; + int sfd; + + sigfillset(&mask); + if (sigprocmask(SIG_SETMASK, &mask, NULL) == -1) { + perror("sigprocmask"); + return -1; + } + + sfd = signalfd(-1, &mask, SFD_CLOEXEC); + if (sfd == -1) { + perror("signalfd"); + return -1; + } + + if (reboot(LINUX_REBOOT_CMD_CAD_OFF)) + perror("cannot disable CTRL+ALT+DEL"); + + return sfd; +} + +void sigreset(void) +{ + sigset_t mask; + + sigemptyset(&mask); + sigprocmask(SIG_SETMASK, &mask, NULL); +}