summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--initd/Makemodule.am2
-rw-r--r--initd/init.h25
-rw-r--r--initd/main.c20
-rw-r--r--initd/runlst.c4
-rw-r--r--initd/signal_linux.c51
5 files changed, 81 insertions, 21 deletions
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 <linux/reboot.h>
+#include <sys/signalfd.h>
#include <sys/reboot.h>
+#include <signal.h>
#include "service.h"
#include "telinit.h"
@@ -117,5 +119,28 @@ service_t *svclist_remove(pid_t pid);
*/
int initenv(void);
+/********** signal_<platform>.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 <errno.h>
#include <poll.h>
-#include <sys/signalfd.h>
-
#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 <https://www.gnu.org/licenses/>.
+ */
+#include <stdio.h>
+
+#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);
+}