diff options
author | Kevin Cernekee <cernekee@gmail.com> | 2011-07-13 09:26:58 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-07-13 09:26:58 +0200 |
commit | 064e99646a233240e91f453ba49f6baeab7c2c70 (patch) | |
tree | b4dabf5fe257da0a51f199fe4fbc1daf2a0e02c7 | |
parent | 80856b37e888612c054158b9fa8a0021dbf8dadf (diff) | |
download | busybox-w32-064e99646a233240e91f453ba49f6baeab7c2c70.tar.gz busybox-w32-064e99646a233240e91f453ba49f6baeab7c2c70.tar.bz2 busybox-w32-064e99646a233240e91f453ba49f6baeab7c2c70.zip |
cttyhack: check sysfs for the name of the active console
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/cttyhack.c | 79 |
1 files changed, 48 insertions, 31 deletions
diff --git a/shell/cttyhack.c b/shell/cttyhack.c index d1ac2cd23..522a1ba73 100644 --- a/shell/cttyhack.c +++ b/shell/cttyhack.c | |||
@@ -14,18 +14,22 @@ | |||
14 | //config: bool "cttyhack" | 14 | //config: bool "cttyhack" |
15 | //config: default y | 15 | //config: default y |
16 | //config: help | 16 | //config: help |
17 | //config: One common problem reported on the mailing list is "can't access tty; | 17 | //config: One common problem reported on the mailing list is the "can't |
18 | //config: job control turned off" error message which typically appears when | 18 | //config: access tty; job control turned off" error message, which typically |
19 | //config: one tries to use shell with stdin/stdout opened to /dev/console. | 19 | //config: appears when one tries to use a shell with stdin/stdout on |
20 | //config: /dev/console. | ||
20 | //config: This device is special - it cannot be a controlling tty. | 21 | //config: This device is special - it cannot be a controlling tty. |
21 | //config: | 22 | //config: |
22 | //config: Proper solution is to use correct device instead of /dev/console. | 23 | //config: The proper solution is to use the correct device instead of |
24 | //config: /dev/console. | ||
23 | //config: | 25 | //config: |
24 | //config: cttyhack provides "quick and dirty" solution to this problem. | 26 | //config: cttyhack provides a "quick and dirty" solution to this problem. |
25 | //config: It analyzes stdin with various ioctls, trying to determine whether | 27 | //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). | 28 | //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. | 29 | //config: On Linux it also checks sysfs for a pointer to the active console. |
28 | //config: Then it executes given program. Opening the device will make | 30 | //config: If cttyhack is able to find the real console device, it closes |
31 | //config: stdin/out/err and reopens that device. | ||
32 | //config: Then it executes the given program. Opening the device will make | ||
29 | //config: that device a controlling tty. This may require cttyhack | 33 | //config: that device a controlling tty. This may require cttyhack |
30 | //config: to be a session leader. | 34 | //config: to be a session leader. |
31 | //config: | 35 | //config: |
@@ -115,33 +119,46 @@ int cttyhack_main(int argc UNUSED_PARAM, char **argv) | |||
115 | close(fd); | 119 | close(fd); |
116 | } else { | 120 | } else { |
117 | /* We don't have ctty (or don't have "/dev/tty" node...) */ | 121 | /* We don't have ctty (or don't have "/dev/tty" node...) */ |
118 | if (0) {} | 122 | do { |
119 | #ifdef TIOCGSERIAL | ||
120 | else if (ioctl(0, TIOCGSERIAL, &u.sr) == 0) { | ||
121 | /* this is a serial console */ | ||
122 | sprintf(console + 8, "S%d", u.sr.line); | ||
123 | } | ||
124 | #endif | ||
125 | #ifdef __linux__ | 123 | #ifdef __linux__ |
126 | else if (ioctl(0, VT_GETSTATE, &u.vt) == 0) { | 124 | int s = open_read_close("/sys/class/tty/console/active", |
127 | /* this is linux virtual tty */ | 125 | console + 5, sizeof(console) - 5 - 1); |
128 | sprintf(console + 8, "S%d" + 1, u.vt.v_active); | 126 | if (s > 0) { |
129 | } | 127 | /* found active console via sysfs (Linux 2.6.38+) */ |
128 | console[5 + s] = '\0'; | ||
129 | break; | ||
130 | } | ||
131 | |||
132 | if (ioctl(0, VT_GETSTATE, &u.vt) == 0) { | ||
133 | /* this is linux virtual tty */ | ||
134 | sprintf(console + 8, "S%d" + 1, u.vt.v_active); | ||
135 | break; | ||
136 | } | ||
130 | #endif | 137 | #endif |
131 | if (console[8]) { | 138 | #ifdef TIOCGSERIAL |
132 | fd = xopen(console, O_RDWR); | 139 | if (ioctl(0, TIOCGSERIAL, &u.sr) == 0) { |
133 | //bb_error_msg("switching to '%s'", console); | 140 | /* this is a serial console, asuming it is named /dev/ttySn */ |
134 | dup2(fd, 0); | 141 | sprintf(console + 8, "S%d", u.sr.line); |
135 | dup2(fd, 1); | 142 | break; |
136 | dup2(fd, 2); | 143 | } |
137 | while (fd > 2) | 144 | #endif |
138 | close(fd--); | 145 | /* nope, could not find it */ |
139 | /* Some other session may have it as ctty, | 146 | goto ret; |
140 | * steal it from them: | 147 | } while (0); |
141 | */ | 148 | |
142 | ioctl(0, TIOCSCTTY, 1); | 149 | fd = xopen(console, O_RDWR); |
143 | } | 150 | //bb_error_msg("switching to '%s'", console); |
151 | dup2(fd, 0); | ||
152 | dup2(fd, 1); | ||
153 | dup2(fd, 2); | ||
154 | while (fd > 2) | ||
155 | close(fd--); | ||
156 | /* Some other session may have it as ctty, | ||
157 | * steal it from them: | ||
158 | */ | ||
159 | ioctl(0, TIOCSCTTY, 1); | ||
144 | } | 160 | } |
145 | 161 | ||
162 | ret: | ||
146 | BB_EXECVP_or_die(argv); | 163 | BB_EXECVP_or_die(argv); |
147 | } | 164 | } |