diff options
-rw-r--r-- | toys/pending/init.c | 132 |
1 files changed, 82 insertions, 50 deletions
diff --git a/toys/pending/init.c b/toys/pending/init.c index facf3b57..559ab09b 100644 --- a/toys/pending/init.c +++ b/toys/pending/init.c @@ -17,8 +17,8 @@ config INIT */ #include "toys.h" -#include<linux/vt.h> -#include<sys/reboot.h> +#include <linux/vt.h> +#include <sys/reboot.h> struct action_list_seed { struct action_list_seed *next; @@ -26,8 +26,7 @@ struct action_list_seed { uint8_t action; char *terminal_name; char *command; -}; -struct action_list_seed *action_list_pointer = NULL; +} *action_list_pointer = NULL; int caught_signal; //INITTAB action defination @@ -44,11 +43,12 @@ static void initialize_console(void) { int fd; char *p = (p = getenv("CONSOLE")) ? p : getenv("console"); + if (!p) { fd = open("/dev/null", O_RDWR); if (fd >= 0) { - while(fd < 2) fd = dup(fd); - while(fd > 2) close(fd--); + while (fd < 2) fd = dup(fd); + while (fd > 2) close(fd--); } } else { fd = open(p, O_RDWR | O_NONBLOCK | O_NOCTTY); @@ -59,6 +59,7 @@ static void initialize_console(void) dup2(fd,2); } } + p = getenv("TERM"); #ifdef VT_OPENQRY int terminal_no; @@ -66,21 +67,22 @@ static void initialize_console(void) if (!p || !strcmp(p,"linux")) putenv((char*)"TERM=vt102"); } else #endif - if (!p) putenv((char*)"TERM=linux"); + if (!p) putenv((char*)"TERM=linux"); } static void set_sane_term(void) { struct termios terminal; + tcgetattr(0, &terminal); - terminal.c_cc[VINTR] = 3;//ctrl-c - terminal.c_cc[VQUIT] = 28;/*ctrl-\*/ - terminal.c_cc[VERASE] = 127;//ctrl-? - terminal.c_cc[VKILL] = 21;//ctrl-u - terminal.c_cc[VEOF] = 4;//ctrl-d - terminal.c_cc[VSTART] = 17;//ctrl-q - terminal.c_cc[VSTOP] = 19;//ctrl-s - terminal.c_cc[VSUSP] = 26;//ctrl-z + terminal.c_cc[VINTR] = 3; //ctrl-c + terminal.c_cc[VQUIT] = 28; /*ctrl-\*/ + terminal.c_cc[VERASE] = 127; //ctrl-? + terminal.c_cc[VKILL] = 21; //ctrl-u + terminal.c_cc[VEOF] = 4; //ctrl-d + terminal.c_cc[VSTART] = 17; //ctrl-q + terminal.c_cc[VSTOP] = 19; //ctrl-s + terminal.c_cc[VSUSP] = 26; //ctrl-z terminal.c_line = 0; terminal.c_cflag = terminal.c_cflag&(CRTSCTS|PARODD|PARENB|CSTOPB|CSIZE|CBAUDEX|CBAUD); @@ -102,18 +104,20 @@ static void set_enviornment(void) static void add_new_action(uint8_t action,char *command,char *term) { struct action_list_seed *x,**y; + y = &action_list_pointer; x = *y; - while(x) { - if (!(strcmp(x->command,command)) && !(strcmp(x->terminal_name,term))) { - *y = x->next;//remove from the list - while(*y) y = &(*y)->next;//traverse through list till end + while (x) { + if (!(strcmp(x->command, command)) && !(strcmp(x->terminal_name, term))) { + *y = x->next; //remove from the list + while(*y) y = &(*y)->next; //traverse through list till end x->next = NULL; break; } y = &(x)->next; x = *y; } + //create a new node if (!x) { x = xzalloc(sizeof(*x)); @@ -140,25 +144,26 @@ static void inittab_parsing(void) } else { while((q = p = get_line(fd))) { //read single line from /etc/inittab char *x; - if((x = strchr(p, '#'))) *x = '\0'; + + if ((x = strchr(p, '#'))) *x = '\0'; line_number++; token_count = 0; action = 0; - while((extracted_token = strsep(&p,":"))) { + while ((extracted_token = strsep(&p,":"))) { token_count++; switch (token_count) { case 1: if (*extracted_token) { - if(!strncmp(extracted_token, "/dev/", 5)) + if (!strncmp(extracted_token, "/dev/", 5)) tty_name = xmsprintf("%s",extracted_token); - else tty_name = xmsprintf("/dev/%s",extracted_token); + else tty_name = xmsprintf("/dev/%s",extracted_token); } else tty_name = xstrdup(""); break; case 2: break; case 3: - for(tmp = act_name, i = 0; *tmp; i++, tmp += strlen(tmp) +1) { - if ( !strcmp(tmp, extracted_token)) { + for (tmp = act_name, i = 0; *tmp; i++, tmp += strlen(tmp) +1) { + if (!strcmp(tmp, extracted_token)) { action = 1 << i; break; } @@ -173,12 +178,14 @@ static void inittab_parsing(void) break; } } //while token + if (q) free(q); if (token_count != 4) continue; if (action) add_new_action(action, command, tty_name); free(tty_name); free(command); - }//while line + } //while line + close(fd); } } @@ -193,10 +200,11 @@ static void run_command(char *command) char *next_command; char *extracted_command; int x = 0; + next_command = strncpy(toybuf, command - hyphen, sizeof(toybuf)); next_command[sizeof(toybuf) - 1] = toybuf[sizeof(toybuf) - 1 ] = '\0'; command = next_command + hyphen; - while((extracted_command = strsep(&next_command," \t"))) { + while ((extracted_command = strsep(&next_command," \t"))) { if (*extracted_command) { final_command[x] = extracted_command; x++; @@ -227,27 +235,31 @@ static pid_t final_run(struct action_list_seed *x) sigprocmask(SIG_BLOCK, &signal_set, NULL); if (x->action & ASKFIRST) pid = fork(); else pid = vfork(); + if (pid > 0) { //parent process or error //unblock the signals sigfillset(&signal_set); sigprocmask(SIG_UNBLOCK, &signal_set, NULL); + return pid; } else if (pid < 0) perror_exit("fork fail"); + //new born child process sigset_t signal_set_c; sigfillset(&signal_set_c); sigprocmask(SIG_UNBLOCK, &signal_set_c, NULL); - setsid();//new session + setsid(); //new session + if (x->terminal_name[0]) { close(0); - fd = open(x->terminal_name,(O_RDWR|O_NONBLOCK),0600); + fd = open(x->terminal_name, (O_RDWR|O_NONBLOCK),0600); if (fd != 0) { - error_msg("Unable to open %s,%s\n",x->terminal_name,strerror(errno)); + error_msg("Unable to open %s,%s\n", x->terminal_name, strerror(errno)); _exit(EXIT_FAILURE); } else { - dup2(0,1); - dup2(0,2); + dup2(0, 1); + dup2(0, 2); } } set_sane_term(); @@ -258,6 +270,7 @@ static pid_t final_run(struct action_list_seed *x) static struct action_list_seed* mark_as_terminated_process(pid_t pid) { struct action_list_seed *x; + if (pid > 0) { for (x = action_list_pointer; x; x = x->next) { if (x->pid == pid) { @@ -266,22 +279,25 @@ static struct action_list_seed* mark_as_terminated_process(pid_t pid) } } } + return NULL; } static void waitforpid(pid_t pid) { if (pid <= 0) return; + for(;;) { pid_t y = wait(NULL); mark_as_terminated_process(y); - if (kill(y,0)) break; + if (kill(y, 0)) break; } } static void run_action_from_list(int action) { pid_t pid; struct action_list_seed *x = action_list_pointer; + for (; x; x = x->next) { if (!(x->action & action)) continue; if (x->action & (SHUTDOWN|ONCE|SYSINIT|CTRLALTDEL|WAIT)) { @@ -307,6 +323,7 @@ static void set_defualt(void) signal(SIGSTOP,SIG_DFL); sigfillset(&signal_set_c); sigprocmask(SIG_UNBLOCK,&signal_set_c, NULL); + run_action_from_list(SHUTDOWN); error_msg("The system is going down NOW!"); kill(-1, SIGTERM); @@ -321,7 +338,9 @@ static void halt_poweroff_reboot_handler(int sig_no) { unsigned int reboot_magic_no = 0; pid_t pid; + set_defualt(); + switch (sig_no) { case SIGUSR1: error_msg("Requesting system halt"); @@ -338,12 +357,15 @@ static void halt_poweroff_reboot_handler(int sig_no) default: break; } + sleep(1); pid = vfork(); + if (pid == 0) { reboot(reboot_magic_no); _exit(EXIT_SUCCESS); } + while(1) sleep(1); } static void restart_init_handler(int sig_no) @@ -351,25 +373,30 @@ static void restart_init_handler(int sig_no) struct action_list_seed *x; pid_t pid; int fd; + for (x = action_list_pointer; x; x = x->next) { if (!(x->action & RESTART)) continue; set_defualt(); + if (x->terminal_name[0]) { close(0); - fd = open(x->terminal_name,(O_RDWR|O_NONBLOCK),0600); + fd = open(x->terminal_name, (O_RDWR|O_NONBLOCK),0600); + if (fd != 0) { - error_msg("Unable to open %s,%s\n",x->terminal_name,strerror(errno)); + error_msg("Unable to open %s,%s\n", x->terminal_name, strerror(errno)); sleep(1); pid = vfork(); + if (pid == 0) { reboot(RB_HALT_SYSTEM); _exit(EXIT_SUCCESS); } + while(1) sleep(1); } else { - dup2(0,1); - dup2(0,2); + dup2(0, 1); + dup2(0, 2); set_sane_term(); run_command(x->command); } @@ -387,18 +414,19 @@ static void pause_handler(int sig_no) { int signal_backup,errno_backup; pid_t pid; + errno_backup = errno; signal_backup = caught_signal; signal(SIGCONT, catch_signal); + while(1) { if (caught_signal == SIGCONT) break; - do - pid = waitpid(-1,NULL,WNOHANG); - while((pid==-1) && (errno=EINTR)); + do pid = waitpid(-1,NULL,WNOHANG); while((pid==-1) && (errno=EINTR)); mark_as_terminated_process(pid); sleep(1); } - signal(SIGCONT,SIG_DFL); + + signal(SIGCONT, SIG_DFL); errno = errno_backup; caught_signal = signal_backup; } @@ -406,10 +434,11 @@ static void pause_handler(int sig_no) static void assign_signal_handler(void) { struct sigaction sig_act; - signal(SIGUSR1, halt_poweroff_reboot_handler);//halt - signal(SIGUSR2, halt_poweroff_reboot_handler);//poweroff - signal(SIGTERM, halt_poweroff_reboot_handler);//reboot - signal(SIGQUIT, restart_init_handler);//restart init + + signal(SIGUSR1, halt_poweroff_reboot_handler); //halt + signal(SIGUSR2, halt_poweroff_reboot_handler); //poweroff + signal(SIGTERM, halt_poweroff_reboot_handler); //reboot + signal(SIGQUIT, restart_init_handler); //restart init memset(&sig_act, 0, sizeof(sig_act)); sigfillset(&sig_act.sa_mask); sigdelset(&sig_act.sa_mask, SIGCONT); @@ -425,6 +454,7 @@ static void assign_signal_handler(void) static int check_if_pending_signals(void) { int signal_caught = 0; + while(1) { int sig = caught_signal; if (!sig) return signal_caught; @@ -433,6 +463,7 @@ static int check_if_pending_signals(void) if (sig == SIGINT) run_action_from_list(CTRLALTDEL); } } + void init_main(void) { if (getpid() != 1) error_exit("Already running"); @@ -451,17 +482,18 @@ void init_main(void) run_action_from_list(WAIT); check_if_pending_signals(); run_action_from_list(ONCE); - while(1) { - int suspected_WNOHANG; - suspected_WNOHANG = check_if_pending_signals(); + while (1) { + int suspected_WNOHANG = check_if_pending_signals(); + run_action_from_list(RESPAWN | ASKFIRST); suspected_WNOHANG = suspected_WNOHANG|check_if_pending_signals(); sleep(1);//let cpu breath suspected_WNOHANG = suspected_WNOHANG|check_if_pending_signals(); if (suspected_WNOHANG) suspected_WNOHANG=WNOHANG; + while(1) { - pid_t pid; - pid = waitpid(-1, NULL, suspected_WNOHANG); + pid_t pid = waitpid(-1, NULL, suspected_WNOHANG); + if (pid <= 0) break; mark_as_terminated_process(pid); suspected_WNOHANG = WNOHANG; |