#define _POSIX_C_SOURCE 200809L #include #include #include #include #include #include "config.h" static void reap(void) { int status; while (waitpid(-1, &status, WNOHANG) > 0) {} } int main(void) { int sigfd = -1; pid_t pid = -1; sigset_t set; if (getpid() != 1) { fprintf(stderr, "4init - you need to run this as PID 1...\n"); return 1; } sigfillset(&set); sigdelset(&set, SIGILL); sigdelset(&set, SIGTRAP); sigdelset(&set, SIGBUS); sigdelset(&set, SIGFPE); sigdelset(&set, SIGSEGV); if (sigprocmask(SIG_SETMASK, &set, NULL) < 0) { perror("sigprocmask"); return 1; } sigfd = signalfd(-1, &set, SFD_CLOEXEC); if (sigfd < 0) { perror("signalfd"); return 1; } pid = fork(); if (pid < 0) { perror("fork"); return 1; } if (pid == 0) { sigset_t empty_set; sigemptyset(&empty_set); sigprocmask(SIG_SETMASK, &empty_set, NULL); if (setsid() == -1) { perror("setsid"); } close(sigfd); execve(rc_path, rc_argv, rc_envp); perror("execve"); _exit(1); } else { struct signalfd_siginfo fdsi; reap(); for (;;) { if (read(sigfd, &fdsi, sizeof(fdsi)) == sizeof(fdsi)) { switch (fdsi.ssi_signo) { case SIGCHLD: reap(); break; } } } } }