sinit.c - sinit - suckless init
(HTM) git clone git://git.suckless.org/sinit
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
sinit.c (1362B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include <sys/types.h>
3 #include <sys/wait.h>
4
5 #include <signal.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <unistd.h>
9
10 #define LEN(x) (sizeof (x) / sizeof *(x))
11 #define TIMEO 30
12
13 static void sigpoweroff(void);
14 static void sigreap(void);
15 static void sigreboot(void);
16 static void spawn(char *const []);
17
18 static struct {
19 int sig;
20 void (*handler)(void);
21 } sigmap[] = {
22 { SIGUSR1, sigpoweroff },
23 { SIGCHLD, sigreap },
24 { SIGALRM, sigreap },
25 { SIGINT, sigreboot },
26 };
27
28 #include "config.h"
29
30 static sigset_t set;
31
32 int
33 main(void)
34 {
35 int sig;
36 size_t i;
37
38 if (getpid() != 1)
39 return 1;
40 chdir("/");
41 sigfillset(&set);
42 sigprocmask(SIG_BLOCK, &set, NULL);
43 spawn(rcinitcmd);
44 while (1) {
45 alarm(TIMEO);
46 sigwait(&set, &sig);
47 for (i = 0; i < LEN(sigmap); i++) {
48 if (sigmap[i].sig == sig) {
49 sigmap[i].handler();
50 break;
51 }
52 }
53 }
54 /* not reachable */
55 return 0;
56 }
57
58 static void
59 sigpoweroff(void)
60 {
61 spawn(rcpoweroffcmd);
62 }
63
64 static void
65 sigreap(void)
66 {
67 while (waitpid(-1, NULL, WNOHANG) > 0)
68 ;
69 alarm(TIMEO);
70 }
71
72 static void
73 sigreboot(void)
74 {
75 spawn(rcrebootcmd);
76 }
77
78 static void
79 spawn(char *const argv[])
80 {
81 switch (fork()) {
82 case 0:
83 sigprocmask(SIG_UNBLOCK, &set, NULL);
84 setsid();
85 execvp(argv[0], argv);
86 perror("execvp");
87 _exit(1);
88 case -1:
89 perror("fork");
90 }
91 }