[git commit master 1/1] FAQ: expand "sh: can't access tty; job control turned off" section
Denys Vlasenko
vda.linux at googlemail.com
Sun Jun 27 00:30:42 UTC 2010
commit: http://git.busybox.net/busybox-website/commit/?id=7407ef75fe4bdb878225f16a8ec6e76bd1830b02
branch: http://git.busybox.net/busybox-website/commit/?id=refs/heads/master
Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
FAQ.html | 42 ++++++++++++++++++++++++++++++++++++++++--
1 files changed, 40 insertions(+), 2 deletions(-)
diff --git a/FAQ.html b/FAQ.html
index 8448505..7c5f2c2 100644
--- a/FAQ.html
+++ b/FAQ.html
@@ -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 />
--
1.7.1
More information about the busybox-cvs
mailing list