[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.
+    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.
+    # Let's try this:
+    exec &lt;/dev/tty1 &gt;/dev/tty1 2&gt;&amp;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 &lt;/dev/tty1 &gt;/dev/tty1 2&gt;&amp;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 &lt;/dev/tty1 &gt;/dev/tty1 2&gt;&amp;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 &lt;/dev/tty1 &gt;/dev/tty1 2&gt;&amp;1'
+    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.
 <hr />

More information about the busybox-cvs mailing list