morpheus-base

morpheus base system
git clone git://git.2f30.org/morpheus-base
Log | Files | Refs

sinit.c (1350B)


      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 
     12 static void sigpoweroff(void);
     13 static void sigreap(void);
     14 static void sigreboot(void);
     15 static void spawn(char *const []);
     16 
     17 static struct {
     18 	int sig;
     19 	void (*handler)(void);
     20 } sigmap[] = {
     21 	{ SIGUSR1, sigpoweroff },
     22 	{ SIGCHLD, sigreap     },
     23 	{ SIGINT,  sigreboot   },
     24 };
     25 
     26 #include "config.h"
     27 
     28 static sigset_t set;
     29 
     30 int
     31 main(void)
     32 {
     33 	int sig;
     34 	size_t i;
     35 
     36 	if (getpid() != 1)
     37 		return EXIT_FAILURE;
     38 	chdir("/");
     39 	sigfillset(&set);
     40 	sigprocmask(SIG_BLOCK, &set, NULL);
     41 	spawn(rcinitcmd);
     42 	while (1) {
     43 		sigwait(&set, &sig);
     44 		for (i = 0; i < LEN(sigmap); i++) {
     45 			if (sigmap[i].sig == sig) {
     46 				sigmap[i].handler();
     47 				break;
     48 			}
     49 		}
     50 	}
     51 	/* not reachable */
     52 	return EXIT_SUCCESS;
     53 }
     54 
     55 static void
     56 sigpoweroff(void)
     57 {
     58 	spawn(rcpoweroffcmd);
     59 }
     60 
     61 static void
     62 sigreap(void)
     63 {
     64 	while (waitpid(-1, NULL, WNOHANG) > 0)
     65 		;
     66 }
     67 
     68 static void
     69 sigreboot(void)
     70 {
     71 	spawn(rcrebootcmd);
     72 }
     73 
     74 static void
     75 spawn(char *const argv[])
     76 {
     77 	pid_t pid;
     78 
     79 	pid = fork();
     80 	if (pid < 0) {
     81 		perror("fork");
     82 	} else if (pid == 0) {
     83 		sigprocmask(SIG_UNBLOCK, &set, NULL);
     84 		setsid();
     85 		execvp(argv[0], argv);
     86 		perror("execvp");
     87 		_exit(EXIT_FAILURE);
     88 	}
     89 }