waitid WALL and build script convolution removal
[muinit.git] / init.c
blob7ca926a98ac0d603b0b28cbb517ee8819cfd0965
1 /*
2 * this code is protected by the GNU affero GPLv3
3 * author:Sylvain BERTRAND <sylvain.bertrand AT legeek DOT net>
4 */
5 #include <ulinux/compiler_misc.h>
6 #include <ulinux/compiler_types.h>
7 #include <ulinux/sysc.h>
8 #include <ulinux/types.h>
9 #include <ulinux/error.h>
10 #include <ulinux/signal/signal.h>
11 #include <ulinux/signal/siginfo.h>
12 #include <ulinux/wait.h>
14 #define INIT_C
15 #include "out.h"
16 #undef INIT_C
17 #include "ulinux_namespace.h"
19 static void sigs_setup(void)
21 ul mask;
22 l r;
24 mask = ~0;
26 OUT(PRE "setting up signals...\n");
27 r = rt_sigprocmask(SIG_BLOCK, &mask, sizeof(mask));
28 if (ISERR(r)) {
29 OUT("ERROR:unable to block all signals (except KILL and STOP)\n");
30 exit_group(-1);
32 OUT("done\n");
35 static i sysstart_clone(void)
37 l r;
38 ul mask;
40 OUT(PRE "clone and execve /bin/sysstart...\n");
41 r = clone(SIGCHLD);
42 if (ISERR(r)) {
43 OUT("ERROR(%ld):unable to clone sysinit for /bin/sysstart\n", r);
44 exit_group(-1);
47 if (r)
48 return (i)r;
50 mask = ~0;
51 r = rt_sigprocmask(SIG_UNBLOCK, &mask, sizeof(mask));
52 if (ISERR(r)) {
53 OUT("ERROR(%ld):unable to unblock all signals for /bin/sysstart\n", r);
54 exit_group(-1);
57 r = execve("/bin/sysstart", 0);
58 if(ISERR(r)) {
59 OUT("ERROR(%ld):unable to execve /bin/sysstart\n", r);
61 exit_group(-1);
64 #ifndef NO_TTY
65 static i getty_spawn(void *tty)
67 l r;
68 ul mask;
69 void *argv[3];
71 argv[0] = "bin/agetty";
72 argv[1] = tty;
73 argv[2] = 0;
75 OUT(PRE "getty %s...\n", tty);
77 r = clone(SIGCHLD);
78 if (ISERR(r)) {
79 OUT("ERROR(%ld):unable to clone for getty(%s)\n", r, tty);
80 exit_group(-1);
83 if (r)
84 return r;/* return the child process id */
86 mask = ~0;
87 r = rt_sigprocmask(SIG_UNBLOCK, &mask, sizeof(mask));
88 if (ISERR(r)) {
89 OUT("ERROR(%ld):unable to unblock all signals for getty(%s)\n", r, tty);
90 exit_group(-1);
93 r = setsid();
94 if (ISERR(r)) {
95 OUT("ERROR(%ld):unable to setsid the getty(%s) clone\n", r, tty);
96 exit_group(-1);
99 r = execve("/bin/agetty", argv);
100 if (ISERR(r)) {
101 OUT("ERROR(%ld):unable to run /bin/agetty(%s)\n", r, tty);
103 exit_group(-1);
105 #endif
107 static void sysstart(void)
109 i pid;
110 l r;
112 pid = sysstart_clone();
113 r = waitid(P_PID, pid, 0, WEXITED|WALL);
114 if (ISERR(r)) {
115 OUT("ERROR(%ld):unable to wait for /bin/sysstart to exit\n", r);
116 exit_group(-1);
120 #ifdef NO_TTY
121 /* minimal, we don't even have ttys to restart */
122 static void main_loop(void)
124 loop {
125 l r;
127 r = waitid(P_ALL, 0, 0, WEXITED|WALL);
128 if (ISERR(r)) {
129 OUT("ERROR(%ld):unable to wait on orphan process terminations\n", r);
133 #else
134 /* we allow ourself 2 ttys to restart */
135 static void main_loop(void)
137 i tty1;
138 i tty2;
140 tty1 = getty_spawn("tty1");
141 tty2 = getty_spawn("tty2");
143 loop {
144 struct siginfo siginfo;
145 l r;
147 r = waitid(P_ALL, 0, &siginfo, WEXITED|WALL);
148 if(ISERR(r)) {
149 OUT("ERROR(%ld):unable to wait on /bin/agetty clone and orphan process terminations\n", r);
150 exit_group(-1);
152 if (siginfo.fields.sigchld.pid == tty1)
153 tty1 = getty_spawn("tty1");
154 else if (siginfo.fields.sigchld.pid == tty2)
155 tty2 = getty_spawn("tty2");
158 #endif
159 void _start(void)
161 sigs_setup();
162 sysstart();
163 main_loop();
165 /* vim: set ts=4 sw=0 noexpandtab: */