hush: implement "silent" optstrings of ":opts"
[oweals/busybox.git] / shell / cttyhack.c
index 6ff867413f431c408cfb5525822a1dec342a7c1f..849fe9e486a1c42a54ee0fde758ea1900c179a8e 100644 (file)
@@ -6,53 +6,53 @@
  */
 #include "libbb.h"
 
-//applet:IF_CTTYHACK(APPLET(cttyhack, BB_DIR_BIN, BB_SUID_DROP))
+//applet:IF_CTTYHACK(APPLET_NOEXEC(cttyhack, cttyhack, BB_DIR_BIN, BB_SUID_DROP, cttyhack))
 
 //kbuild:lib-$(CONFIG_CTTYHACK) += cttyhack.o
 
 //config:config CTTYHACK
-//config:      bool "cttyhack"
+//config:      bool "cttyhack (2.5 kb)"
 //config:      default y
 //config:      help
-//config:        One common problem reported on the mailing list is the "can't
-//config:        access tty; job control turned off" error message, which typically
-//config:        appears when one tries to use a shell with stdin/stdout on
-//config:        /dev/console.
-//config:        This device is special - it cannot be a controlling tty.
+//config:      One common problem reported on the mailing list is the "can't
+//config:      access tty; job control turned off" error message, which typically
+//config:      appears when one tries to use a shell with stdin/stdout on
+//config:      /dev/console.
+//config:      This device is special - it cannot be a controlling tty.
 //config:
-//config:        The proper solution is to use the correct device instead of
-//config:        /dev/console.
+//config:      The proper solution is to use the correct device instead of
+//config:      /dev/console.
 //config:
-//config:        cttyhack provides a "quick and dirty" solution to this problem.
-//config:        It analyzes stdin with various ioctls, trying to determine whether
-//config:        it is a /dev/ttyN or /dev/ttySN (virtual terminal or serial line).
-//config:        On Linux it also checks sysfs for a pointer to the active console.
-//config:        If cttyhack is able to find the real console device, it closes
-//config:        stdin/out/err and reopens that device.
-//config:        Then it executes the given program. Opening the device will make
-//config:        that device a controlling tty. This may require cttyhack
-//config:        to be a session leader.
+//config:      cttyhack provides a "quick and dirty" solution to this problem.
+//config:      It analyzes stdin with various ioctls, trying to determine whether
+//config:      it is a /dev/ttyN or /dev/ttySN (virtual terminal or serial line).
+//config:      On Linux it also checks sysfs for a pointer to the active console.
+//config:      If cttyhack is able to find the real console device, it closes
+//config:      stdin/out/err and reopens that device.
+//config:      Then it executes the given program. Opening the device will make
+//config:      that device a controlling tty. This may require cttyhack
+//config:      to be a session leader.
 //config:
-//config:        Example for /etc/inittab (for busybox init):
+//config:      Example for /etc/inittab (for busybox init):
 //config:
-//config:        ::respawn:/bin/cttyhack /bin/sh
+//config:      ::respawn:/bin/cttyhack /bin/sh
 //config:
-//config:        Starting an interactive shell from boot shell script:
+//config:      Starting an interactive shell from boot shell script:
 //config:
-//config:        setsid cttyhack sh
+//config:      setsid cttyhack sh
 //config:
-//config:        Giving controlling tty to shell running with PID 1:
+//config:      Giving controlling tty to shell running with PID 1:
 //config:
-//config:        # exec cttyhack sh
+//config:      # exec cttyhack sh
 //config:
-//config:        Without cttyhack, you need to know exact tty name,
-//config:        and do something like this:
+//config:      Without cttyhack, you need to know exact tty name,
+//config:      and do something like this:
 //config:
-//config:        # exec setsid sh -c 'exec sh </dev/tty1 >/dev/tty1 2>&1'
+//config:      # exec setsid sh -c 'exec sh </dev/tty1 >/dev/tty1 2>&1'
 //config:
-//config:        Starting getty on a controlling tty from a shell script:
+//config:      Starting getty on a controlling tty from a shell script:
 //config:
-//config:        # getty 115200 $(cttyhack)
+//config:      # getty 115200 $(cttyhack)
 
 //usage:#define cttyhack_trivial_usage
 //usage:       "[PROG ARGS]"
@@ -123,15 +123,22 @@ int cttyhack_main(int argc UNUSED_PARAM, char **argv)
                         * TIOCGSERIAL check, which assumes that all
                         * serial lines follow /dev/ttySn convention -
                         * which is not always the case.
-                        * Therefore, we use this methos first:
+                        * Therefore, we use this method first:
                         */
                        int s = open_read_close("/sys/class/tty/console/active",
                                console + 5, sizeof(console) - 5);
                        if (s > 0) {
-                               /* found active console via sysfs (Linux 2.6.38+)
-                                * sysfs string looks like "ttyS0\n" so zap the newline:
+                               char *last;
+                               /* Found active console via sysfs (Linux 2.6.38+).
+                                * It looks like "[tty0 ]ttyS0\n" so zap the newline:
                                 */
                                console[4 + s] = '\0';
+                               /* If there are multiple consoles,
+                                * take the last one:
+                                */
+                               last = strrchr(console + 5, ' ');
+                               if (last)
+                                       overlapping_strcpy(console + 5, last + 1);
                                break;
                        }