36#include <pedigree/log.h>
41extern void pedigree_reboot();
43static int g_Running = 1;
46static void sigterm(
int sig) {
51static pid_t start(
const char* proc) {
54 int fork_errno = errno;
55 pedigree_log(LOG_ALERT,
"init: fork failed for %s: errno=%d (%s)", proc, fork_errno,
56 strerror(fork_errno));
60 pedigree_log(LOG_INFO,
"init: starting %s...", proc);
62 int exec_errno = errno;
63 pedigree_log(LOG_ALERT,
"init: loading %s failed: errno=%d (%s)", proc, exec_errno,
64 strerror(exec_errno));
67 pedigree_log(LOG_INFO,
"init: fork succeeded for %s: child=%d", proc, f);
71 char basename_buf[PATH_MAX];
72 strncpy(basename_buf, proc, PATH_MAX);
78 memset(&init, 0,
sizeof(init));
79 gettimeofday(&tv, NULL);
80 init.ut_type = INIT_PROCESS;
83 strncpy(init.ut_id, basename(basename_buf),
sizeof(init.ut_id));
90static void startAndWait(
const char* proc) {
91 pid_t f = start(proc);
95static void runScripts() {
96 struct dirent** namelist;
98 int count = scandir(
"/etc/init.d", &namelist, 0, alphasort);
100 pedigree_log(LOG_CRIT,
"could not scan /etc/init.d: %s", strerror(errno));
102 pedigree_log(LOG_INFO,
"init: %d init script entries found", count);
103 for (
int i = 0; i < count; ++i) {
104 char script[PATH_MAX];
105 snprintf(script, PATH_MAX,
"/etc/init.d/%s", namelist[i]->d_name);
107 if (!strcmp(namelist[i]->d_name,
".") || !strcmp(namelist[i]->d_name,
"..")) {
115 int r = stat(script, &st);
117 if (S_ISREG(st.st_mode) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) {
119 pedigree_log(LOG_INFO,
"init: running %s", script);
120 startAndWait(script);
122 pedigree_log(LOG_INFO,
"init: not running %s (not a file, or not executable)", script);
125 pedigree_log(LOG_INFO,
"init: cannot stat %s (broken symlink?)", script);
133int main(
int argc,
char** argv) {
134 pedigree_log(LOG_INFO,
"init: starting...");
137 int fd = open(UTMP_FILE, O_CREAT | O_RDWR, 0664);
149 gettimeofday(&tv, NULL);
152 memset(&boot, 0,
sizeof(boot));
153 boot.ut_type = BOOT_TIME;
161 signal(SIGTERM, sigterm);
165 pedigree_log(LOG_INFO,
"init: hosted build, triggering a reboot");
172 pedigree_log(LOG_INFO,
"init: complete!");
177 pid_t changer = waitpid(-1, &status, g_Running == 0 ? WNOHANG : 0);
179 pedigree_log(LOG_INFO,
"init: child %d exited with status %d", changer, WEXITSTATUS(status));
180 }
else if (!g_Running) {
181 pedigree_log(LOG_INFO,
182 "init: no more children and have been asked to "
183 "terminate, terminating...");
194 if (p && (p->ut_type == INIT_PROCESS && p->ut_pid == changer))
205 memset(&dead, 0,
sizeof(dead));
206 gettimeofday(&tv, NULL);
207 dead.ut_type = DEAD_PROCESS;
208 dead.ut_pid = changer;
210 strncpy(dead.ut_id, p->ut_id,
sizeof(dead.ut_id));