Source: https://gist.github.com/rofl0r/6168719
Code: Select all
#define _XOPEN_SOURCE 700
#include <signal.h>
#include <unistd.h>
int main()
{
sigset_t set;
int status;
if (getpid() != 1) return 1;
sigfillset(&set);
sigprocmask(SIG_BLOCK, &set, 0);
if (fork()) for (;;) wait(&status);
sigprocmask(SIG_UNBLOCK, &set, 0);
setsid();
setpgid(0, 0);
return execve("/etc/rc", (char *[]){ "rc", 0 }, (char *[]){ 0 });
}
First it checks whether the user is root exiting if the user in not root. Then, it blocks all messages before forking the process to produce a child that is used to do the actual OS loading. The fork works as follows: in the calling process, the parent process, fork() returns the non-zero PID of the child while in the newly created child process it returns 0. Execution in the child follows from the same point in the parent. This means, the parent process will enter the infinite loop that repeatedly calls wait(&status) which clears zombies from the kernel's process table completely freeing their resources. In the child, as a result of fork() returning 0, the infinite loops is skipped and the succeeding lines of code are executed. The first instruction is to unblock messages so that newly created processes can communicate. At the end, it calls execve which replaces the child process with a shell that runs /etc/rc. Under Debian the rc script is found under /etc/init.d.
I found using /etc/init.d/rc directly does not successfully load Debian or Devuan provided /etc/init.d is properly filled with scripts and rcN and not emplty. I used a simple shell script to first call "rc S" and then "rc 2". This successfully loaded a useable operating system.
The custom script to load the OS:
Code: Select all
#!/bin/sh
if /etc/init.d/rc S; then
/etc/init.d/rc 2
fi
Modified Felker's C init to load Devuan/Debian provided there /etc/init.d is properly populated and /etc/rcN directories are filled with working symbolic links.
Code: Select all
#define _XOPEN_SOURCE 700
#include <signal.h>
#include <unistd.h>
int main()
{
sigset_t set;
int status;
if (getpid() != 1) return 1;
sigfillset(&set);
sigprocmask(SIG_BLOCK, &set, 0);
if (fork()) for (;;) wait(&status);
sigprocmask(SIG_UNBLOCK, &set, 0);
setsid();
setpgid(0, 0);
return execve("/sbin/osloader.sh", (char *[]){ 0 }, (char *[]){ 0 });
}