Apply last_patch47 from vodz to fix several problems, such as the ash "job
authorEric Andersen <andersen@codepoet.org>
Wed, 3 Jul 2002 11:08:10 +0000 (11:08 -0000)
committerEric Andersen <andersen@codepoet.org>
Wed, 3 Jul 2002 11:08:10 +0000 (11:08 -0000)
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.

init/init.c

index 8b68a0556a6a4e8f8de367300c5a8f100593cf7b..4724ad7d541641728959d7aaf5a82a14575c866c 100644 (file)
@@ -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();