diff options
Diffstat (limited to 'shell/cttyhack.c')
-rw-r--r-- | shell/cttyhack.c | 66 |
1 files changed, 64 insertions, 2 deletions
diff --git a/shell/cttyhack.c b/shell/cttyhack.c index 67736ad62..7a5e1ffd2 100644 --- a/shell/cttyhack.c +++ b/shell/cttyhack.c | |||
@@ -6,6 +6,62 @@ | |||
6 | */ | 6 | */ |
7 | #include "libbb.h" | 7 | #include "libbb.h" |
8 | 8 | ||
9 | //applet:IF_CTTYHACK(APPLET(cttyhack, _BB_DIR_BIN, _BB_SUID_DROP)) | ||
10 | |||
11 | //kbuild:lib-$(CONFIG_CTTYHACK) += cttyhack.o | ||
12 | |||
13 | //config:config CTTYHACK | ||
14 | //config: bool "cttyhack" | ||
15 | //config: default y | ||
16 | //config: help | ||
17 | //config: One common problem reported on the mailing list is "can't access tty; | ||
18 | //config: job control turned off" error message which typically appears when | ||
19 | //config: one tries to use shell with stdin/stdout opened to /dev/console. | ||
20 | //config: This device is special - it cannot be a controlling tty. | ||
21 | //config: | ||
22 | //config: Proper solution is to use correct device instead of /dev/console. | ||
23 | //config: | ||
24 | //config: cttyhack provides "quick and dirty" solution to this problem. | ||
25 | //config: It analyzes stdin with various ioctls, trying to determine whether | ||
26 | //config: it is a /dev/ttyN or /dev/ttySN (virtual terminal or serial line). | ||
27 | //config: If it detects one, it closes stdin/out/err and reopens that device. | ||
28 | //config: Then it executes given program. Opening the device will make | ||
29 | //config: that device a controlling tty. This may require cttyhack | ||
30 | //config: to be a session leader. | ||
31 | //config: | ||
32 | //config: Example for /etc/inittab (for busybox init): | ||
33 | //config: | ||
34 | //config: ::respawn:/bin/cttyhack /bin/sh | ||
35 | //config: | ||
36 | //config: Starting an interactive shell from boot shell script: | ||
37 | //config: | ||
38 | //config: setsid cttyhack sh | ||
39 | //config: | ||
40 | //config: Giving controlling tty to shell running with PID 1: | ||
41 | //config: | ||
42 | //config: # exec cttyhack sh | ||
43 | //config: | ||
44 | //config: Without cttyhack, you need to know exact tty name, | ||
45 | //config: and do something like this: | ||
46 | //config: | ||
47 | //config: # exec setsid sh -c 'exec sh </dev/tty1 >/dev/tty1 2>&1' | ||
48 | //config: | ||
49 | |||
50 | //usage:#define cttyhack_trivial_usage | ||
51 | //usage: "PROG ARGS" | ||
52 | //usage:#define cttyhack_full_usage "\n\n" | ||
53 | //usage: "Give PROG a controlling tty if possible." | ||
54 | //usage: "\nExample for /etc/inittab (for busybox init):" | ||
55 | //usage: "\n ::respawn:/bin/cttyhack /bin/sh" | ||
56 | //usage: "\nGiving controlling tty to shell running with PID 1:" | ||
57 | //usage: "\n $ exec cttyhack sh" | ||
58 | //usage: "\nStarting interactive shell from boot shell script:" | ||
59 | //usage: "\n setsid cttyhack sh" | ||
60 | |||
61 | #if !defined(__linux__) && !defined(TIOCGSERIAL) && !ENABLE_WERROR | ||
62 | # warning cttyhack will not be able to detect a controlling tty on this system | ||
63 | #endif | ||
64 | |||
9 | /* From <linux/vt.h> */ | 65 | /* From <linux/vt.h> */ |
10 | struct vt_stat { | 66 | struct vt_stat { |
11 | unsigned short v_active; /* active vt */ | 67 | unsigned short v_active; /* active vt */ |
@@ -59,13 +115,19 @@ int cttyhack_main(int argc UNUSED_PARAM, char **argv) | |||
59 | close(fd); | 115 | close(fd); |
60 | } else { | 116 | } else { |
61 | /* We don't have ctty (or don't have "/dev/tty" node...) */ | 117 | /* We don't have ctty (or don't have "/dev/tty" node...) */ |
62 | if (ioctl(0, TIOCGSERIAL, &u.sr) == 0) { | 118 | if (0) {} |
119 | #ifdef TIOCGSERIAL | ||
120 | else if (ioctl(0, TIOCGSERIAL, &u.sr) == 0) { | ||
63 | /* this is a serial console */ | 121 | /* this is a serial console */ |
64 | sprintf(console + 8, "S%d", u.sr.line); | 122 | sprintf(console + 8, "S%d", u.sr.line); |
65 | } else if (ioctl(0, VT_GETSTATE, &u.vt) == 0) { | 123 | } |
124 | #endif | ||
125 | #ifdef __linux__ | ||
126 | else if (ioctl(0, VT_GETSTATE, &u.vt) == 0) { | ||
66 | /* this is linux virtual tty */ | 127 | /* this is linux virtual tty */ |
67 | sprintf(console + 8, "S%d" + 1, u.vt.v_active); | 128 | sprintf(console + 8, "S%d" + 1, u.vt.v_active); |
68 | } | 129 | } |
130 | #endif | ||
69 | if (console[8]) { | 131 | if (console[8]) { |
70 | fd = xopen(console, O_RDWR); | 132 | fd = xopen(console, O_RDWR); |
71 | //bb_error_msg("switching to '%s'", console); | 133 | //bb_error_msg("switching to '%s'", console); |