diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b1b7161 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +init diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..4dc4d36 --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2015-2020, Adrien Gallouët +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f5c3d54 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +DESTDIR ?= + +.PHONY: all +all: init + +.PHONY: install +install: init + install -s init $(DESTDIR)/ + +.PHONY: clean +clean: + rm -f init diff --git a/init.c b/init.c new file mode 100644 index 0000000..a995f3e --- /dev/null +++ b/init.c @@ -0,0 +1,117 @@ +#define _GNU_SOURCE + +#include +#include +#include +#include + +#include +#include +#include + +static void +spawn(const char *cmd) +{ + pid_t pid = fork(); + + if (pid == (pid_t)-1) { + perror("fork"); + return; + } + + if (pid == (pid_t)0) { + static sigset_t set; + sigfillset(&set); + sigprocmask(SIG_UNBLOCK, &set, NULL); + setsid(); + execl(cmd, cmd, (char *)NULL); + perror("execl"); + _exit(1); + } + + while (waitpid(-1, NULL, 0) != pid); +} + +static void +init_fs(void) +{ + chdir("/"); + + if (mount(NULL, "/", NULL, MS_NOSUID|MS_REMOUNT, NULL)) + perror("remount(/)"); + + mkdir("/dev", 0755); + mkdir("/proc", 0755); + mkdir("/tmp", 01777); + mkdir("/sys", 0755); + + if (mount("none", "/dev", "devtmpfs", 0, NULL)) + perror("mount(dev)"); + + if (mount("none", "/proc", "proc", 0, NULL)) + perror("mount(proc)"); + + if (mount("none", "/sys", "sysfs", 0, NULL)) + perror("mount(sys)"); + + if (mount("none", "/sys/fs/cgroup", "cgroup2", 0, NULL)) + perror("mount(cgroup2)"); + + mkdir("/dev/pts", 0755); + mkdir("/dev/shm", 0755); + + if (mount("devpts", "/dev/pts", "devpts", 0, "gid=5,mode=0620,ptmxmode=0666")) + perror("mount(devpts)"); +} + +static void +init_console(void) +{ + int fd = open("/dev/console", O_RDWR | O_NONBLOCK | O_NOCTTY); + + if (fd < 0) { + perror("open(console)"); + return; + } + + dup2(fd, 0); + dup2(fd, 1); + dup2(fd, 2); + + if (fd > 2) + close(fd); +} + +static void +init_term(void) +{ + if (getenv("TERM")) + return; + + putenv("TERM=linux"); +} + +int +main(void) +{ + if (getpid() != 1) + return 1; + + setsid(); + + init_fs(); + init_console(); + init_term(); + + static sigset_t set; + sigfillset(&set); + sigprocmask(SIG_BLOCK, &set, NULL); + + while (1) { + spawn("/etc/boot"); + spawn("/etc/reboot"); + sleep(1); + } + + return 0; +}