66 lines
1.1 KiB
C
66 lines
1.1 KiB
C
#define INIT
|
|
#include <stdio.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <signal.h>
|
|
#include <sys/reboot.h>
|
|
#include <sys/wait.h>
|
|
#include "config.h"
|
|
|
|
void poweroff(int sig) {
|
|
printf("Syncing...\n");
|
|
|
|
sync();
|
|
sleep(5);
|
|
|
|
if (sig == SIGUSR1)
|
|
reboot(RB_POWER_OFF);
|
|
|
|
else if (sig == SIGUSR2)
|
|
reboot(RB_AUTOBOOT);
|
|
}
|
|
|
|
void execute(char *argv[]) {
|
|
pid_t pid;
|
|
if ((pid = fork()) == 0) {
|
|
setsid();
|
|
execvp(argv[0], argv);
|
|
|
|
fprintf(stderr, "init: Failed to run %s\nRebooting...\n", argv[0]);
|
|
poweroff(SIGUSR2);
|
|
}
|
|
}
|
|
|
|
int main(void) {
|
|
if (getpid() != 1) {
|
|
fprintf(stderr, "init: PID Must be 1\n");
|
|
return 1;
|
|
}
|
|
|
|
chdir("/");
|
|
printf("%s\n", INIT_MSG);
|
|
|
|
sigset_t set;
|
|
sigemptyset(&set);
|
|
sigaddset(&set, SIGUSR1);
|
|
sigaddset(&set, SIGUSR2);
|
|
|
|
/* Start main service */
|
|
sigprocmask(SIG_BLOCK, &set, NULL);
|
|
execute(INIT_START);
|
|
|
|
/* Sig handler */
|
|
int sig = 0;
|
|
while (1) {
|
|
if (sigwait(&set, &sig) == 0)
|
|
if (sig == SIGUSR2 || sig == SIGUSR1) {
|
|
execute(INIT_POWEROFF);
|
|
poweroff(sig);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|