diff options
author | Eric Andersen | 2002-07-03 11:08:10 +0000 |
---|---|---|
committer | Eric Andersen | 2002-07-03 11:08:10 +0000 |
commit | 599e3ce163c43c3dfb24d06f8f707c783bc9ab9c (patch) | |
tree | 309378de5168889bcfe2bd65704167c47f59da20 /init/init.c | |
parent | 935daf2d0d65edacfafe32868174c6c634bd35c3 (diff) | |
download | busybox-599e3ce163c43c3dfb24d06f8f707c783bc9ab9c.zip busybox-599e3ce163c43c3dfb24d06f8f707c783bc9ab9c.tar.gz |
Apply last_patch47 from vodz to fix several problems, such as the ash "job
control turned off" bug, console_setup() was called with a closed file
descriptor, setsid() inconsistancy, and silly string handling bugs. I have
modified his patch to allow the askfirst init actions to have a controlling
terminal.
Diffstat (limited to 'init/init.c')
-rw-r--r-- | init/init.c | 55 |
1 files changed, 31 insertions, 24 deletions
diff --git a/init/init.c b/init/init.c index 8b68a05..4724ad7 100644 --- a/init/init.c +++ b/init/init.c @@ -484,15 +484,11 @@ static pid_t run(struct init_action *a) if ((pid = fork()) == 0) { /* Clean up */ - ioctl(0, TIOCNOTTY, 0); close(0); close(1); close(2); sigprocmask(SIG_SETMASK, &omask, NULL); - /* Create a new session and make ourself the process group leader */ - setsid(); - /* Reset signal handlers that were set by the parent process */ signal(SIGUSR1, SIG_DFL); signal(SIGUSR2, SIG_DFL); @@ -503,6 +499,11 @@ static pid_t run(struct init_action *a) signal(SIGSTOP, SIG_DFL); signal(SIGTSTP, SIG_DFL); + /* Create a new session and make ourself the process + * group leader for non-interactive jobs */ + if ((a->action & (RESPAWN))==0) + setsid(); + /* Open the new terminal device */ if ((fd = device_open(a->terminal, O_RDWR|O_NOCTTY)) < 0) { if (stat(a->terminal, &sb) != 0) { @@ -513,19 +514,26 @@ static pid_t run(struct init_action *a) message(LOG | CONSOLE, "\rBummer, can't open %s\n", a->terminal); _exit(1); } + + /* Non-interactive jobs should not get a controling tty */ + if ((a->action & (RESPAWN))==0) + (void)ioctl(fd, TIOCSCTTY, 0); + /* Make sure the terminal will act fairly normal for us */ set_term(0); + /* Setup stdin, stdout, stderr for the new process so + * they point to the supplied terminal */ + dup(fd); + dup(fd); - /* If the init Action requires up to wait, then force the - * supplied terminal to be the controlling tty. */ - if (a->action & (SYSINIT|WAIT|CTRLALTDEL|SHUTDOWN|RESTART|ASKFIRST)) { + /* For interactive jobs, create a new session + * and become the process group leader */ + if ((a->action & (RESPAWN))) + setsid(); - /* Take over the controlling tty */ - ioctl(fd, TIOCSCTTY, 1); - /* Setup stdin, stdout, stderr for the new process so - * they point to the supplied terminal */ - dup(fd); - dup(fd); + /* If the init Action requires us to wait, then force the + * supplied terminal to be the controlling tty. */ + if (a->action & (SYSINIT|WAIT|CTRLALTDEL|SHUTDOWN|RESTART)) { /* Now fork off another process to just hang around */ if ((pid = fork()) < 0) { @@ -542,13 +550,11 @@ static pid_t run(struct init_action *a) signal(SIGCHLD, SIG_DFL); /* Wait for child to exit */ - while ((tmp_pid = waitpid(pid, &junk, 0)) != pid) { - if (tmp_pid < 0 && errno == ECHILD) - break; - } + while ((tmp_pid = waitpid(pid, &junk, 0)) != pid) + ; /* See if stealing the controlling tty back is necessary */ - pgrp = tcgetpgrp(tmp_pid); + pgrp = tcgetpgrp(fd); if (pgrp != getpid()) _exit(0); @@ -570,9 +576,6 @@ static pid_t run(struct init_action *a) } /* Now fall though to actually execute things */ - } else { - dup(fd); - dup(fd); } /* See if any special /bin/sh requiring characters are present */ @@ -1079,15 +1082,19 @@ extern int init_main(int argc, char **argv) /* Figure out what kernel this is running */ kernelVersion = get_kernel_revision(); + /* Figure out where the default console should be */ + console_init(); + /* Close whatever files are open, and reset the console. */ close(0); close(1); close(2); - /* Figure out where the default console should be */ - console_init(); - + if(device_open(console, O_RDWR|O_NOCTTY)==0) { set_term(0); + close(0); + } + chdir("/"); setsid(); |