/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