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 /shell | |
| 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>
Diffstat (limited to 'shell')
| -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 | } |
