aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Cernekee <cernekee@gmail.com>2011-07-13 09:26:58 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2011-07-13 09:26:58 +0200
commit064e99646a233240e91f453ba49f6baeab7c2c70 (patch)
treeb4dabf5fe257da0a51f199fe4fbc1daf2a0e02c7
parent80856b37e888612c054158b9fa8a0021dbf8dadf (diff)
downloadbusybox-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.c79
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
162ret:
146 BB_EXECVP_or_die(argv); 163 BB_EXECVP_or_die(argv);
147} 164}