diff options
| author | uxtbd <dev@kthread.dev> | 2026-08-18 14:40:18 +0200 |
|---|---|---|
| committer | uxtbd <dev@kthread.dev> | 2026-08-18 14:40:18 +0200 |
| commit | 1ea2764a30cd2fbad93a1a6d8b13ce1e5fdb8f8c (patch) | |
| tree | 23cbf7bd324159ee618901e201fce82579e8510e /4init/4init.c | |
| parent | Initial commit (diff) | |
| download | 4suite-1ea2764a30cd2fbad93a1a6d8b13ce1e5fdb8f8c.tar.gz 4suite-1ea2764a30cd2fbad93a1a6d8b13ce1e5fdb8f8c.tar.bz2 4suite-1ea2764a30cd2fbad93a1a6d8b13ce1e5fdb8f8c.tar.xz 4suite-1ea2764a30cd2fbad93a1a6d8b13ce1e5fdb8f8c.zip | |
4init: minimal but functional init
Diffstat (limited to '')
| -rw-r--r-- | 4init/4init.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/4init/4init.c b/4init/4init.c new file mode 100644 index 0000000..50807b6 --- /dev/null +++ b/4init/4init.c | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | #define _POSIX_C_SOURCE 200809L | ||
| 2 | |||
| 3 | #include <signal.h> | ||
| 4 | #include <stdio.h> | ||
| 5 | #include <sys/signalfd.h> | ||
| 6 | #include <sys/wait.h> | ||
| 7 | #include <unistd.h> | ||
| 8 | |||
| 9 | #include "config.h" | ||
| 10 | |||
| 11 | static void reap(void) | ||
| 12 | { | ||
| 13 | int status; | ||
| 14 | while (waitpid(-1, &status, WNOHANG) > 0) {} | ||
| 15 | } | ||
| 16 | |||
| 17 | int main(void) | ||
| 18 | { | ||
| 19 | int sigfd = -1; | ||
| 20 | pid_t pid = -1; | ||
| 21 | sigset_t set; | ||
| 22 | |||
| 23 | if (getpid() != 1) { | ||
| 24 | fprintf(stderr, "4init - you need to run this as PID 1...\n"); | ||
| 25 | return 1; | ||
| 26 | } | ||
| 27 | |||
| 28 | sigfillset(&set); | ||
| 29 | sigdelset(&set, SIGILL); | ||
| 30 | sigdelset(&set, SIGTRAP); | ||
| 31 | sigdelset(&set, SIGBUS); | ||
| 32 | sigdelset(&set, SIGFPE); | ||
| 33 | sigdelset(&set, SIGSEGV); | ||
| 34 | |||
| 35 | if (sigprocmask(SIG_SETMASK, &set, NULL) < 0) { | ||
| 36 | perror("sigprocmask"); | ||
| 37 | return 1; | ||
| 38 | } | ||
| 39 | |||
| 40 | sigfd = signalfd(-1, &set, SFD_CLOEXEC); | ||
| 41 | if (sigfd < 0) { | ||
| 42 | perror("signalfd"); | ||
| 43 | return 1; | ||
| 44 | } | ||
| 45 | |||
| 46 | pid = fork(); | ||
| 47 | if (pid < 0) { | ||
| 48 | perror("fork"); | ||
| 49 | return 1; | ||
| 50 | } | ||
| 51 | |||
| 52 | if (pid == 0) { | ||
| 53 | sigset_t empty_set; | ||
| 54 | |||
| 55 | sigemptyset(&empty_set); | ||
| 56 | sigprocmask(SIG_SETMASK, &empty_set, NULL); | ||
| 57 | |||
| 58 | if (setsid() == -1) { | ||
| 59 | perror("setsid"); | ||
| 60 | } | ||
| 61 | |||
| 62 | close(sigfd); | ||
| 63 | |||
| 64 | execve(rc_path, rc_argv, rc_envp); | ||
| 65 | perror("execve"); | ||
| 66 | _exit(1); | ||
| 67 | } else { | ||
| 68 | struct signalfd_siginfo fdsi; | ||
| 69 | |||
| 70 | reap(); | ||
| 71 | |||
| 72 | for (;;) { | ||
| 73 | if (read(sigfd, &fdsi, sizeof(fdsi)) == sizeof(fdsi)) { | ||
| 74 | switch (fdsi.ssi_signo) { | ||
| 75 | case SIGCHLD: | ||
| 76 | reap(); | ||
| 77 | break; | ||
| 78 | } | ||
| 79 | } | ||
| 80 | } | ||
| 81 | } | ||
| 82 | } | ||
