/* * init.c version 20130705 * Daniel Cegielka * Public domain. */ #include #include #include #include #include #include #include static void sigchild(int sig) { while(waitpid(-1, NULL, WNOHANG) > 0); } static void openconsole(void) { int fd; if((fd = open("/dev/console", O_RDWR|O_NOCTTY)) >= 0){ dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); if(fd > 2) close(fd); } } int main(int argc, char **argv) { int i, fd, l; struct sigaction sa; pid_t t; if(getpid() != 1) return 1; for(i = 0, l = 0; i < argc; i++) l = strlen(argv[i]) + 1; if(l > 1){ memset(argv[0], 0, l); strncpy(argv[0], "init", l - 1); } for(i = 1; i < NSIG; i++) if(i != SIGCHLD) (void)signal(i, SIG_IGN); reboot(RB_DISABLE_CAD); if((fd = open("/dev/console", O_RDWR|O_NOCTTY)) >= 0){ ioctl(fd, KDSIGACCEPT, SIGWINCH); close(fd); } else ioctl(0, KDSIGACCEPT, SIGWINCH); for(i = 0; i < 3; i++){ close(i); open("/dev/null", O_RDWR, 0); } if(!fork()){ setsid(); openconsole(); tcsetpgrp(0, getpgrp()); execl("/bin/sh", "sh", "/etc/rc", NULL); while(waitpid(t, NULL, 0) != t); } sigemptyset(&sa.sa_mask); sa.sa_sigaction = 0; sa.sa_flags = SA_RESTART|SA_NOCLDSTOP; sa.sa_handler = sigchild; sigaction(SIGCHLD, &sa, 0); for(;;) pause(); }