aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--toys/pending/init.c132
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;