From 1e1073235796c838d5e1a3255f88ec97575e3582 Mon Sep 17 00:00:00 2001 From: WlodekM Date: Mon, 7 Apr 2025 10:50:14 +0300 Subject: uh --- sbin/init/sinit.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 sbin/init/sinit.c (limited to 'sbin/init/sinit.c') diff --git a/sbin/init/sinit.c b/sbin/init/sinit.c new file mode 100644 index 0000000..b29f880 --- /dev/null +++ b/sbin/init/sinit.c @@ -0,0 +1,96 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include + +#include +#include +#include +#include + +#define LEN(x) (sizeof (x) / sizeof *(x)) +#define TIMEO 30 + +static void sigpoweroff(void); +static void sigreap(void); +static void sigreboot(void); +static void spawn(char *const []); + +static struct { + int sig; + void (*handler)(void); +} sigmap[] = { + { SIGUSR1, sigpoweroff }, + { SIGCHLD, sigreap }, + { SIGALRM, sigreap }, + { SIGINT, sigreboot }, +}; + +/* See LICENSE file for copyright and license details. */ + +static char *const rcinitcmd[] = { "/bin/zsh", NULL }; +static char *const rcrebootcmd[] = { "/bin/rc.shutdown", "reboot", NULL }; +static char *const rcpoweroffcmd[] = { "/bin/rc.shutdown", "poweroff", NULL }; + + +static sigset_t set; + +int +main(void) +{ + int sig; + size_t i; + + if (getpid() != 1) + return 1; + chdir("/"); + sigfillset(&set); + sigprocmask(SIG_BLOCK, &set, NULL); + spawn(rcinitcmd); + while (1) { + alarm(TIMEO); + sigwait(&set, &sig); + for (i = 0; i < LEN(sigmap); i++) { + if (sigmap[i].sig == sig) { + sigmap[i].handler(); + break; + } + } + } + /* not reachable */ + return 0; +} + +static void +sigpoweroff(void) +{ + spawn(rcpoweroffcmd); +} + +static void +sigreap(void) +{ + while (waitpid(-1, NULL, WNOHANG) > 0) + ; + alarm(TIMEO); +} + +static void +sigreboot(void) +{ + spawn(rcrebootcmd); +} + +static void +spawn(char *const argv[]) +{ + switch (fork()) { + case 0: + sigprocmask(SIG_UNBLOCK, &set, NULL); + setsid(); + execvp(argv[0], argv); + perror("execvp"); + _exit(1); + case -1: + perror("fork"); + } +} -- cgit 1.4.1-2-gfad0