diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-06-27 00:30:42 (GMT) |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-06-27 00:30:42 (GMT) |
| commit | 7407ef75fe4bdb878225f16a8ec6e76bd1830b02 (patch) | |
| tree | 119104c341162a5503397c9b02ae970bb993731d | |
| parent | db0065bf54ede6c2fd905bc230103bc89e29d79f (diff) | |
| download | busybox-website-7407ef75fe4bdb878225f16a8ec6e76bd1830b02.tar.gz busybox-website-7407ef75fe4bdb878225f16a8ec6e76bd1830b02.tar.bz2 | |
FAQ: expand "sh: can't access tty; job control turned off" section
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
| -rw-r--r-- | FAQ.html | 42 |
1 files changed, 40 insertions, 2 deletions
@@ -583,11 +583,49 @@ int main(int argc, char *argv) terminal. This typically happens when you run your shell on /dev/console. The kernel will not provide a controlling terminal on the /dev/console device. Your should run your shell on a normal tty such as tty1 or ttyS0 - and everything will work perfectly. If you <em>REALLY</em> want your shell + and everything will work. +</p> +<p> + Example: you booted into your machine with init=/bin/sh + and got "sh: can't access tty" error because sh has its stdio + opened to /dev/console. You want to reopen stdio to, say, /dev/tty1 + and thus acquire a controlling tty. +</p> +<pre> + # Let's try this: + exec </dev/tty1 >/dev/tty1 2>&1 + # No, doesn't work: even if opening /dev/tty1 gave sh the ctty, + # sh wouldn't know it - it checks for ctty just once at startup. + + # Let's try re-execing sh: + exec </dev/tty1 >/dev/tty1 2>&1 + exec sh + # Got "sh: can't access tty" again. Why? + # The reason is somewhat obscure: kernel starts process with PID=1 + # (in this case, shell) with SID=0 and PGID=0, not with SID=1 and PGID=1 + # as you'd expect. IOW: our sh is not a session leader, and therefore + # cannot acquire ctty by opening /dev/tty1 (or any other tty). + + # Let's try making us a session leader: + exec setsid sh + exec </dev/tty1 >/dev/tty1 2>&1 + exec sh + # Yes, this worked! + + # This can be combined into one command, + # but need to be careful and perform these operations + # in the correct order: + # 1. make ourself session leader, + # 2. open /dev/tty1 and thus acquire a ctty, + # 3. re-execute the shell, allowing it to notice that it has ctty: + exec setsid sh -c 'exec sh </dev/tty1 >/dev/tty1 2>&1' +</pre> +<p> + If you <em>REALLY</em> want your shell to run on /dev/console, then you can hack your kernel (if you are into that sortof thing) by changing drivers/char/tty_io.c to change the lines where it sets "noctty = 1;" to instead set it to "0". I recommend you instead - run your shell on a real console... + run your shell on a real console. </p> <hr /> |
