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 }