34
|
1 /* oneit.c, tiny one-process init replacement.
|
|
2 *
|
|
3 * Copyright 2005 by Rob Landley <rob@landley.net>.
|
|
4 */
|
|
5
|
|
6 #include "toys.h"
|
|
7 #include <sys/reboot.h>
|
|
8
|
|
9 // The minimum amount of work necessary to get ctrl-c and such to work is:
|
|
10 //
|
|
11 // - Fork a child (PID 1 is special: can't exit, has various signals blocked).
|
|
12 // - Do a setsid() (so we have our own session).
|
|
13 // - In the child, attach stdio to /dev/tty0 (/dev/console is special)
|
|
14 // - Exec the rest of the command line.
|
|
15 //
|
|
16 // PID 1 then reaps zombies until the child process it spawned exits, at which
|
|
17 // point it calls sync() and reboot(). I could stick a kill -1 in there.
|
|
18
|
|
19 int oneit_main(void)
|
|
20 {
|
|
21 int i;
|
|
22 pid_t pid;
|
|
23
|
|
24 // Create a new child process.
|
|
25 pid = vfork();
|
|
26 if (pid) {
|
|
27
|
|
28 // pid 1 just reaps zombies until it gets its child, then halts the system.
|
|
29 while (pid!=wait(&i));
|
|
30 sync();
|
|
31 reboot(toys.optflags ? RB_POWER_OFF : RB_AUTOBOOT);
|
|
32 }
|
|
33
|
|
34 // Redirect stdio to /dev/tty0, with new session ID, so ctrl-c works.
|
|
35 setsid();
|
|
36 for (i=0; i<3; i++) {
|
|
37 close(i);
|
|
38 open("/dev/tty0",O_RDWR);
|
|
39 }
|
|
40
|
|
41 // Can't xexec() here because we vforked so we don't want to error_exit().
|
|
42 toy_exec(toys.optargs);
|
|
43 execvp(*toys.optargs, toys.optargs);
|
|
44 _exit(127);
|
|
45 }
|