/init.c (e37d41440898ce916b2821ab7501eee2579a8357) (3582 bytes) (mode 100644) (type blob)
/*******************************************************************************
this code is protected by the GNU affero GPLv3
author:Sylvain BERTRAND <sylvain.bertrand AT gmail dot com>
*******************************************************************************/
#include <ulinux/compiler_misc.h>
#include <ulinux/compiler_types.h>
#include <ulinux/sysc.h>
#include <ulinux/types.h>
#include <ulinux/error.h>
#include <ulinux/signal/signal.h>
#include <ulinux/signal/siginfo.h>
#include <ulinux/wait.h>
#define INIT_C
#include "out.h"
#undef INIT_C
#include "ulinux_namespace.h"
static void sigs_setup(void)
{
ul mask=(~0);
l r;
OUT(PRE "setting up signals...\n");
r=rt_sigprocmask(SIG_BLOCK,&mask,sizeof(mask));
if(ISERR(r)){
OUT("ERROR:unable to block all signals (except KILL and STOP)\n");
exit_group(-1);
}
OUT("done\n");
}
static i sysstart_clone(void)
{
l r;
ul mask;
OUT(PRE "clone and execve /sbin/sysstart...\n");
r=clone(SIGCHLD);
if(ISERR(r)){
OUT("ERROR(%ld):unable to clone sysinit for /sbin/sysstart\n",r);
exit_group(-1);
}
if(r) return (i)r;
mask=(~0);
r=rt_sigprocmask(SIG_UNBLOCK,&mask,sizeof(mask));
if(ISERR(r)){
OUT("ERROR(%ld):unable to unblock all signals for /sbin/sysstart\n",r);
exit_group(-1);
}
r=execve("/sbin/sysstart",0);
if(ISERR(r)) {OUT("ERROR(%ld):unable to execve /sbin/sysstart\n",r);}
exit_group(-1);
#ifdef __GNUC__
return 0;/*unreachable not detected at the end of function*/
#endif
}
#ifndef NO_TTY
static i getty_spawn(void *tty)
{
l r;
ul mask;
void *argv[]={"/sbin/agetty",tty,0};/*0 for envp is not "portable"*/
OUT(PRE "getty %s...\n",tty);
r=clone(SIGCHLD);
if(ISERR(r)){
OUT("ERROR(%ld):unable to clone for getty(%s)\n",r,tty);
exit_group(-1);
}
if(r) return r;/*return the child process id*/
mask=(~0);
r=rt_sigprocmask(SIG_UNBLOCK,&mask,sizeof(mask));
if(ISERR(r)){
OUT("ERROR(%ld):unable to unblock all signals for getty(%s)\n",r,tty);
exit_group(-1);
}
r=setsid();
if(ISERR(r)){
OUT("ERROR(%ld):unable to setsid the getty(%s) clone\n",r,tty);
exit_group(-1);
}
r=execve("/sbin/agetty",argv);
if(ISERR(r)) {OUT("ERROR(%ld):unable to run /sbin/agetty(%s)\n",r,tty);}
exit_group(-1);
#ifdef __GNUC__
return 0;/*unreachable not detected at the end of function*/
#endif
}
#endif
static void sysstart(void)
{
i pid=sysstart_clone();
l r=waitid(P_PID,pid,0,WEXITED);
if(ISERR(r)){
OUT("ERROR(%ld):unable to wait for /sbin/sysstart to exit\n",r);
exit_group(-1);
}
}
#ifdef NO_TTY
/*minimal, we don't even have ttys to restart*/
static void main_loop(void)
{
loop{
l r=waitid(P_ALL,0,0,WEXITED);
if(ISERR(r)){
OUT("ERROR(%ld):unable to wait on orphan process terminations\n",r);
}
}
unreachable();
}
#else
/*we allow ourself 2 ttys to restart*/
static void main_loop(void)
{
i tty1=getty_spawn("tty1");
i tty2=getty_spawn("tty2");
loop{
struct siginfo siginfo;
l r=waitid(P_ALL,0,&siginfo,WEXITED);
if(ISERR(r)){
OUT("ERROR(%ld):unable to wait on /sbin/agetty clone and orphan process terminations\n",r);
exit_group(-1);
}
if(siginfo.fields.sigchld.pid==tty1) tty1=getty_spawn("tty1");
else if(siginfo.fields.sigchld.pid==tty2) tty2=getty_spawn("tty2");
/*ignore the other children*/
}
unreachable();
}
#endif
void _start(void)
{
#ifndef QUIET
static u8 dprintf_buf[DPRINTF_BUF_SZ];
g_dprintf_buf=dprintf_buf;
#endif
sigs_setup();
sysstart();
main_loop();
unreachable();
}
Mode |
Type |
Size |
Ref |
File |
100644 |
blob |
748 |
0f3164a05c66ef3302de1ce131b97055e55c5202 |
README |
100644 |
blob |
268 |
4d60db557e795bbf987b70e52ac12dfbd40d32cf |
TODO |
100644 |
blob |
3582 |
e37d41440898ce916b2821ab7501eee2579a8357 |
init.c |
100755 |
blob |
6986 |
5aaefc93a599bef9d782f2cf21aa53a891f82900 |
make |
100644 |
blob |
701 |
9cc13a5eeb354f7d2410c2a8f741216103069d20 |
out.h |
040000 |
tree |
- |
2060db7e0ccf8f8a07fbeb3dffaf21d8ab25ddd8 |
script |
040000 |
tree |
- |
30cfb73bbb46661479d865b19291742b0b828b76 |
ulinux |
100644 |
blob |
1025 |
f0dd85b20ca0d40d43eddee1286653abfef2ad1c |
ulinux_namespace.h |
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"
Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/sylware/muinit
Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/sylware/muinit
Clone this repository using git:
git clone git://git.rocketgit.com/user/sylware/muinit
You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a
merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main