annotate toys/other/oneit.c @ 1727:c0ef9b7976f0 draft

Use xsignal() instead of signal().
author Rob Landley <rob@landley.net>
date Tue, 10 Mar 2015 11:07:28 -0500
parents b2b2d214727a
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
694
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
1 /* oneit.c - tiny init replacement to launch a single child process.
34
c1f4f9101af7 Add oneit.
Rob Landley <rob@landley.net>
parents:
diff changeset
2 *
194
30a6db5a95c2 Add comments about SUSv3 specs (or lack thereof).
Rob Landley <rob@landley.net>
parents: 186
diff changeset
3 * Copyright 2005, 2007 by Rob Landley <rob@landley.net>.
233
d4176f3f3835 Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents: 195
diff changeset
4
1725
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
5 USE_ONEIT(NEWTOY(oneit, "^<1nc:p3[!pn]", TOYFLAG_SBIN))
234
163498bf547b Move NEWTOY() list from end of toylist.h to generated/newtoys.h.
Rob Landley <rob@landley.net>
parents: 233
diff changeset
6
233
d4176f3f3835 Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents: 195
diff changeset
7 config ONEIT
694
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
8 bool "oneit"
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
9 default y
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
10 help
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
11 usage: oneit [-p] [-c /dev/tty0] command [...]
233
d4176f3f3835 Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents: 195
diff changeset
12
1725
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
13 Simple init program that runs a single supplied command line with a
694
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
14 controlling tty (so CTRL-C can kill it).
233
d4176f3f3835 Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents: 195
diff changeset
15
1725
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
16 -c Which console device to use (/dev/console doesn't do CTRL-C, etc).
694
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
17 -p Power off instead of rebooting when command exits.
1725
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
18 -r Restart child when it exits.
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
19 -3 Write 32 bit PID of each exiting reparented process to fd 3 of child.
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
20 (Blocking writes, child must read to avoid eventual deadlock.)
233
d4176f3f3835 Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents: 195
diff changeset
21
1725
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
22 Spawns a single child process (because PID 1 has signals blocked)
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
23 in its own session, reaps zombies until the child exits, then
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
24 reboots the system (or powers off with -p, or restarts the child with -r).
233
d4176f3f3835 Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents: 195
diff changeset
25 */
34
c1f4f9101af7 Add oneit.
Rob Landley <rob@landley.net>
parents:
diff changeset
26
674
7e846e281e38 New build infrastructure to generate FLAG_ macros and TT alias, #define FOR_commandname before #including toys.h to trigger it. Rename DEFINE_GLOBALS() to just GLOBALS() (because I could never remember if it was DECLARE_GLOBALS). Convert existing commands to use new infrastructure, and replace optflag constants with FLAG_ macros where appropriate.
Rob Landley <rob@landley.net>
parents: 656
diff changeset
27 #define FOR_oneit
34
c1f4f9101af7 Add oneit.
Rob Landley <rob@landley.net>
parents:
diff changeset
28 #include "toys.h"
c1f4f9101af7 Add oneit.
Rob Landley <rob@landley.net>
parents:
diff changeset
29 #include <sys/reboot.h>
c1f4f9101af7 Add oneit.
Rob Landley <rob@landley.net>
parents:
diff changeset
30
674
7e846e281e38 New build infrastructure to generate FLAG_ macros and TT alias, #define FOR_commandname before #including toys.h to trigger it. Rename DEFINE_GLOBALS() to just GLOBALS() (because I could never remember if it was DECLARE_GLOBALS). Convert existing commands to use new infrastructure, and replace optflag constants with FLAG_ macros where appropriate.
Rob Landley <rob@landley.net>
parents: 656
diff changeset
31 GLOBALS(
694
786841fdb1e0 Reindent to two spaces per level. Remove vi: directives that haven't worked right in years (ubuntu broke its' vim implementation). Remove trailing spaces. Add/remove blank lines. Re-wordwrap in places. Update documentation with new coding style.
Rob Landley <rob@landley.net>
parents: 674
diff changeset
32 char *console;
237
7cb15eae1664 Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS()
Rob Landley <rob@landley.net>
parents: 234
diff changeset
33 )
7cb15eae1664 Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS()
Rob Landley <rob@landley.net>
parents: 234
diff changeset
34
34
c1f4f9101af7 Add oneit.
Rob Landley <rob@landley.net>
parents:
diff changeset
35 // The minimum amount of work necessary to get ctrl-c and such to work is:
c1f4f9101af7 Add oneit.
Rob Landley <rob@landley.net>
parents:
diff changeset
36 //
c1f4f9101af7 Add oneit.
Rob Landley <rob@landley.net>
parents:
diff changeset
37 // - Fork a child (PID 1 is special: can't exit, has various signals blocked).
c1f4f9101af7 Add oneit.
Rob Landley <rob@landley.net>
parents:
diff changeset
38 // - Do a setsid() (so we have our own session).
c1f4f9101af7 Add oneit.
Rob Landley <rob@landley.net>
parents:
diff changeset
39 // - In the child, attach stdio to /dev/tty0 (/dev/console is special)
c1f4f9101af7 Add oneit.
Rob Landley <rob@landley.net>
parents:
diff changeset
40 // - Exec the rest of the command line.
c1f4f9101af7 Add oneit.
Rob Landley <rob@landley.net>
parents:
diff changeset
41 //
c1f4f9101af7 Add oneit.
Rob Landley <rob@landley.net>
parents:
diff changeset
42 // PID 1 then reaps zombies until the child process it spawned exits, at which
c1f4f9101af7 Add oneit.
Rob Landley <rob@landley.net>
parents:
diff changeset
43 // point it calls sync() and reboot(). I could stick a kill -1 in there.
c1f4f9101af7 Add oneit.
Rob Landley <rob@landley.net>
parents:
diff changeset
44
1725
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
45 // Perform actions in response to signals. (Only root can send us signals.)
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
46 static void oneit_signaled(int signal)
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
47 {
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
48 int action = RB_AUTOBOOT;
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
49
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
50 toys.signal = signal;
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
51 if (signal == SIGUSR1) action = RB_HALT_SYSTEM;
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
52 if (signal == SIGUSR2) action = RB_POWER_OFF;
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
53
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
54 // PID 1 can't call reboot() because it kills the task that calls it,
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
55 // which causes the kernel to panic before the actual reboot happens.
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
56 sync();
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
57 if (!vfork()) reboot(action);
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
58 }
195
9dc48c97d6f9 Add -c option to oneit, to specify console other than /dev/tty0.
Rob Landley <rob@landley.net>
parents: 194
diff changeset
59
186
25447caf1b4b Change command main() functions to return void, and exit(toys.exitval) from
Rob Landley <rob@landley.net>
parents: 156
diff changeset
60 void oneit_main(void)
34
c1f4f9101af7 Add oneit.
Rob Landley <rob@landley.net>
parents:
diff changeset
61 {
1725
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
62 int i, pid, pipes[] = {SIGUSR1, SIGUSR2, SIGTERM, SIGINT};
34
c1f4f9101af7 Add oneit.
Rob Landley <rob@landley.net>
parents:
diff changeset
63
1725
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
64 if (FLAG_3) {
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
65 // Ensure next available filehandle is #3
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
66 while (open("/", 0) < 3);
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
67 close(3);
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
68 close(4);
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
69 if (pipe(pipes)) perror_exit("pipe");
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
70 fcntl(4, F_SETFD, FD_CLOEXEC);
34
c1f4f9101af7 Add oneit.
Rob Landley <rob@landley.net>
parents:
diff changeset
71 }
156
1e8f4b05cb65 Remove trailing whitespace (thanks to Charlie Shepherd), and a couple comment
Rob Landley <rob@landley.net>
parents: 34
diff changeset
72
1725
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
73 // Setup signal handlers for signals of interest
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
74 for (i = 0; i<ARRAY_LEN(pipes); i++) xsignal(pipes[i], oneit_signaled);
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
75
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
76 while (!toys.signal) {
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
77
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
78 // Create a new child process.
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
79 pid = vfork();
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
80 if (pid) {
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
81
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
82 // pid 1 reaps zombies until it gets its child, then halts system.
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
83 // We ignore the return value of write (what would we do with it?)
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
84 // but save it in a variable we never read to make fortify shut up.
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
85 // (Real problem is if pid2 never reads, write() fills pipe and blocks.)
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
86 while (pid != wait(&i)) if (FLAG_3) i = write(4, &pid, 4);
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
87 if (toys.optflags & FLAG_n) continue;
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
88
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
89 oneit_signaled((toys.optflags & FLAG_p) ? SIGUSR2 : SIGTERM);
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
90 } else {
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
91 // Redirect stdio to /dev/tty0, with new session ID, so ctrl-c works.
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
92 setsid();
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
93 for (i=0; i<3; i++) {
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
94 close(i);
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
95 // Remember, O_CLOEXEC is backwards for xopen()
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
96 xopen(TT.console ? TT.console : "/dev/tty0", O_RDWR|O_CLOEXEC);
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
97 }
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
98
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
99 // Can't xexec() here, we vforked so we don't want to error_exit().
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
100 toy_exec(toys.optargs);
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
101 execvp(*toys.optargs, toys.optargs);
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
102 perror_msg("%s not in PATH=%s", *toys.optargs, getenv("PATH"));
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
103
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
104 break;
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
105 }
34
c1f4f9101af7 Add oneit.
Rob Landley <rob@landley.net>
parents:
diff changeset
106 }
c1f4f9101af7 Add oneit.
Rob Landley <rob@landley.net>
parents:
diff changeset
107
1725
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
108 // Give reboot() time to kick in, or avoid rapid spinning if exec failed
b2b2d214727a Upgrade oneit with -r (restart), -3 (send exiting PID values to child), and signal handling.
Rob Landley <rob@landley.net>
parents: 1429
diff changeset
109 sleep(5);
34
c1f4f9101af7 Add oneit.
Rob Landley <rob@landley.net>
parents:
diff changeset
110 _exit(127);
c1f4f9101af7 Add oneit.
Rob Landley <rob@landley.net>
parents:
diff changeset
111 }