summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoruxtbd <dev@kthread.dev>2026-08-18 14:40:18 +0200
committeruxtbd <dev@kthread.dev>2026-08-18 14:40:18 +0200
commit1ea2764a30cd2fbad93a1a6d8b13ce1e5fdb8f8c (patch)
tree23cbf7bd324159ee618901e201fce82579e8510e
parentInitial commit (diff)
download4suite-1ea2764a30cd2fbad93a1a6d8b13ce1e5fdb8f8c.tar.gz
4suite-1ea2764a30cd2fbad93a1a6d8b13ce1e5fdb8f8c.zip
4init: minimal but functional init
-rw-r--r--.gitignore54
-rw-r--r--4init/.gitignore1
-rw-r--r--4init/4init.c82
-rw-r--r--4init/Makefile21
-rw-r--r--4init/README.md5
-rw-r--r--4init/config.h17
-rw-r--r--4init/config.mk5
-rw-r--r--README.md4
8 files changed, 134 insertions, 55 deletions
diff --git a/.gitignore b/.gitignore
index 845cda6..5761abc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,55 +1 @@
-# Prerequisites
-*.d
-
-# Object files
*.o
-*.ko
-*.obj
-*.elf
-
-# Linker output
-*.ilk
-*.map
-*.exp
-
-# Precompiled Headers
-*.gch
-*.pch
-
-# Libraries
-*.lib
-*.a
-*.la
-*.lo
-
-# Shared objects (inc. Windows DLLs)
-*.dll
-*.so
-*.so.*
-*.dylib
-
-# Executables
-*.exe
-*.out
-*.app
-*.i*86
-*.x86_64
-*.hex
-
-# Debug files
-*.dSYM/
-*.su
-*.idb
-*.pdb
-
-# Kernel Module Compile Results
-*.mod*
-*.cmd
-.tmp_versions/
-modules.order
-Module.symvers
-Mkfile.old
-dkms.conf
-
-# debug information files
-*.dwo
diff --git a/4init/.gitignore b/4init/.gitignore
new file mode 100644
index 0000000..79cfb58
--- /dev/null
+++ b/4init/.gitignore
@@ -0,0 +1 @@
+4init \ No newline at end of file
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 @@
+#define _POSIX_C_SOURCE 200809L
+
+#include <signal.h>
+#include <stdio.h>
+#include <sys/signalfd.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#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;
+ }
+ }
+ }
+ }
+}
diff --git a/4init/Makefile b/4init/Makefile
new file mode 100644
index 0000000..e56e105
--- /dev/null
+++ b/4init/Makefile
@@ -0,0 +1,21 @@
+include config.mk
+
+BIN = 4init
+OBJ = 4init.o
+
+all: $(BIN)
+
+$(BIN): $(OBJ)
+ $(CC) $(LDFLAGS) -o $@ $(OBJ)
+
+$(OBJ): config.h
+
+install: all
+ mkdir -pv $(DESTDIR)$(PREFIX)/bin
+ cp -fv $(BIN) $(DESTDIR)$(PREFIX)/bin
+
+uninstall: all
+ rm -f $(DESTDIR)$(PREFIX)/bin/$(BIN)
+
+clean: all
+ rm -f 4init.o 4init
diff --git a/4init/README.md b/4init/README.md
new file mode 100644
index 0000000..44fbde5
--- /dev/null
+++ b/4init/README.md
@@ -0,0 +1,5 @@
+# 4init: minimal but functional init
+
+It's only purpose is to manage processes, it by defaults calls 4rc, but you can change that in `config.h`, it's started as PID 1, and if it crashes, the kernel will panic, read the article in Wikipedia if you want to know more.
+
+Inspired by [rofl0r](https://gist.github.com/rofl0r/6168719)'s minimal init. \ No newline at end of file
diff --git a/4init/config.h b/4init/config.h
new file mode 100644
index 0000000..6c36ccf
--- /dev/null
+++ b/4init/config.h
@@ -0,0 +1,17 @@
+#ifndef CONFIG_H
+#define CONFIG_H
+
+static const char *rc_path = "/usr/bin/4rc";
+
+static char *const rc_argv[] = {
+ "4rc",
+ NULL
+};
+
+static char *const rc_envp[] = {
+ "PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/sbin",
+ "TERM=linux",
+ NULL
+};
+
+#endif // CONFIG_H
diff --git a/4init/config.mk b/4init/config.mk
new file mode 100644
index 0000000..ab7e752
--- /dev/null
+++ b/4init/config.mk
@@ -0,0 +1,5 @@
+PREFIX = /usr/local
+
+CC = musl-gcc
+CFLAGS = -std=c99 -Wextra -Wall -Os -fhardened
+LDFLAGS = -s -static
diff --git a/README.md b/README.md
index 52b57ff..de0e8a0 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,4 @@
# 4suite
-A self-contained C boot stack (init, rc, logger, user) with Plan 9 namespace isolation
+
+A self-contained C boot stack (init, rc, logger, user).
+Each component has it's own README.md, worth checking it out.