Re: Booting into /bin/bash

From: Richard B. Johnson (root@chaos.analogic.com)
Date: Fri Sep 15 2000 - 09:52:07 EST


On Thu, 14 Sep 2000, Ion Badulescu wrote:

> On Fri, 15 Sep 2000, Russell King wrote:
>
> > There are two ways for a tty to become a controlling terminal:
> >
> > 1. First tty opened after a successful setsid() call.
> > 2. using the TIOCSCTTY ioctl after a successful setsid() call.
> >
> > Both will only suceed if the current process does not already have a
> > controlling terminal.
>
> Both will fail for pid=1, which does not already have a controlling
> terminal.
>
> > Therefore...
> >
> > Richard B. Johnson writes:
> > > setsid() = 6
> > > open("/dev/tty1", O_RDWR|O_NONBLOCK) = 3
>
> Look at his setsid() result. It is 6, so it was called from pid=6. Trust
> me, it DOES NOT WORK for pid=1.
>
> Adding a setsid() call at the very beginning of init() in init/main.c
> makes pid=1 a process leader, at a time when it's still possible (no other
> threads are running). After that, another kernel change can give it
> /dev/console as its controlling terminal, or it can acquire the
> controlling terminal itself via ioctl(0, TIOCSCTTY, 1).
>

The __only__ way I have found to get a controlling terminal is to
fork() first. Then all the 'rules' seem to work. However, it is
not all that clean because:

(1) The first ioctl(TIOCNOTTY) returns -1 with errno set to EINVAL.
However, without this call, I can't get a controlling terminal later.

(2) The first open() after setsid() does not automatically make it
a controlling terminal.

(3) Without the initial fork() nothing works in a logical way.

        switch(fork()) {
        case 0:
            (void)ioctl(0, TIOCNOTTY, 0);
            (void)close(0);
            (void)close(1);
            (void)close(2);
            (void)setsid();
            (void)open("/dev/tty1", O_RDWR|O_NDELAY,0);
            flags = fcntl(0, F_GETFL, 0);
            flags &= ~O_NDELAY;
            (void)fcntl(0, F_SETFL, flags);
            (void)dup(0);
            (void)dup(0);
            (void)tcsetattr(0, TCSANOW, &term);
            if(ioctl(0, TIOCSCTTY, 1)<0)
               perror("ioctl(TIOCSCTTY)");
            i = 0;
            sa.sa_handler = SIG_DFL;
            for(i=1; i< NSIG; i++)
                (void)sigaction(i, &sa, NULL);
            sa.sa_handler = reaper;
            (void)sigaction(SIGCHLD, &sa, NULL);
            (void)execve(argv[0], argv, environ);
            perror("execve");
            exit(1);

Cheers,
Dick Johnson

Penguin : Linux version 2.2.15 on an i686 machine (797.90 BogoMips).

"Memory is like gasoline. You use it up when you are running. Of
course you get it all back when you reboot..."; Actual explanation
obtained from the Micro$oft help desk.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Fri Sep 15 2000 - 21:00:25 EST