Mercurial > vinit
view vinit.c @ 7:7d40d4ae7377 default tip @
misc: update copyright years
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sun, 02 Jan 2022 10:26:58 +0100 |
parents | 3db6ca1fe07d |
children |
line wrap: on
line source
/* * vinit.c -- the Vanilla Linux init * * Copyright (c) 2021-2022 David Demelier <markand@malikania.fr> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include <sys/wait.h> #include <errno.h> #include <signal.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <stdnoreturn.h> #include <string.h> #include <unistd.h> static char * const rcinit[] = { SYSCONFDIR "/vinit.start", NULL }; static char * const rchalt[] = { SYSCONFDIR "/vinit.shutdown", "halt", NULL }; static char * const rcpoweroff[] = { SYSCONFDIR "/vinit.shutdown", "poweroff", NULL }; static char * const rcreboot[] = { SYSCONFDIR "/vinit.shutdown", "reboot", NULL }; static sigset_t set; noreturn static void die(const char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); exit(1); } static void spawn(char * const args[]) { switch (fork()) { case 0: sigprocmask(SIG_UNBLOCK, &set, NULL); setsid(); execv(args[0], args); perror("execv"); exit(1); case -1: perror("fork"); default: break; } } int main(void) { int sig; if (getpid() != 1) die("abort: must be ran as PID 1\n"); if (chdir("/") < 0) die("abort: %s\n", strerror(errno)); sigfillset(&set); sigprocmask(SIG_BLOCK, &set, NULL); spawn(rcinit); for (;;) { sigwait(&set, &sig); /* Match busybox defaults. */ switch (sig) { case SIGUSR1: spawn(rchalt); break; case SIGUSR2: spawn(rcpoweroff); break; case SIGTERM: spawn(rcreboot); break; case SIGCHLD: while (waitpid(-1, NULL, WNOHANG) > 0) continue; default: break; } } }