sinit

suckless init
git clone git://git.2f30.org/sinit
Log | Files | Refs | README | 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 }