aboutsummaryrefslogtreecommitdiff
path: root/shell/cttyhack.c
diff options
context:
space:
mode:
Diffstat (limited to 'shell/cttyhack.c')
-rw-r--r--shell/cttyhack.c71
1 files changed, 43 insertions, 28 deletions
diff --git a/shell/cttyhack.c b/shell/cttyhack.c
index 4261289b4..6ff867413 100644
--- a/shell/cttyhack.c
+++ b/shell/cttyhack.c
@@ -50,9 +50,12 @@
50//config: 50//config:
51//config: # exec setsid sh -c 'exec sh </dev/tty1 >/dev/tty1 2>&1' 51//config: # exec setsid sh -c 'exec sh </dev/tty1 >/dev/tty1 2>&1'
52//config: 52//config:
53//config: Starting getty on a controlling tty from a shell script:
54//config:
55//config: # getty 115200 $(cttyhack)
53 56
54//usage:#define cttyhack_trivial_usage 57//usage:#define cttyhack_trivial_usage
55//usage: "PROG ARGS" 58//usage: "[PROG ARGS]"
56//usage:#define cttyhack_full_usage "\n\n" 59//usage:#define cttyhack_full_usage "\n\n"
57//usage: "Give PROG a controlling tty if possible." 60//usage: "Give PROG a controlling tty if possible."
58//usage: "\nExample for /etc/inittab (for busybox init):" 61//usage: "\nExample for /etc/inittab (for busybox init):"
@@ -108,59 +111,71 @@ int cttyhack_main(int argc UNUSED_PARAM, char **argv)
108 char paranoia[sizeof(struct serial_struct) * 3]; 111 char paranoia[sizeof(struct serial_struct) * 3];
109 } u; 112 } u;
110 113
111 if (!*++argv) {
112 bb_show_usage();
113 }
114
115 strcpy(console, "/dev/tty"); 114 strcpy(console, "/dev/tty");
116 fd = open(console, O_RDWR); 115 fd = open(console, O_RDWR);
117 if (fd >= 0) { 116 if (fd < 0) {
118 /* We already have ctty, nothing to do */
119 close(fd);
120 } else {
121 /* 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...) */
122 do { 118 do {
123#ifdef __linux__ 119#ifdef __linux__
120 /* Note that this method does not use _stdin_.
121 * Thus, "cttyhack </dev/something" can't be used.
122 * However, this method is more reliable than
123 * TIOCGSERIAL check, which assumes that all
124 * serial lines follow /dev/ttySn convention -
125 * which is not always the case.
126 * Therefore, we use this methos first:
127 */
124 int s = open_read_close("/sys/class/tty/console/active", 128 int s = open_read_close("/sys/class/tty/console/active",
125 console + 5, sizeof(console) - 5 - 1); 129 console + 5, sizeof(console) - 5);
126 if (s > 0) { 130 if (s > 0) {
127 /* found active console via sysfs (Linux 2.6.38+) */ 131 /* found active console via sysfs (Linux 2.6.38+)
128 console[5 + s] = '\0'; 132 * sysfs string looks like "ttyS0\n" so zap the newline:
133 */
134 console[4 + s] = '\0';
129 break; 135 break;
130 } 136 }
131 137
132 if (ioctl(0, VT_GETSTATE, &u.vt) == 0) { 138 if (ioctl(0, VT_GETSTATE, &u.vt) == 0) {
133 /* this is linux virtual tty */ 139 /* this is linux virtual tty */
134 sprintf(console + 8, "S%d" + 1, u.vt.v_active); 140 sprintf(console + 8, "S%u" + 1, (int)u.vt.v_active);
135 break; 141 break;
136 } 142 }
137#endif 143#endif
138#ifdef TIOCGSERIAL 144#ifdef TIOCGSERIAL
139 if (ioctl(0, TIOCGSERIAL, &u.sr) == 0) { 145 if (ioctl(0, TIOCGSERIAL, &u.sr) == 0) {
140 /* this is a serial console, asuming it is named /dev/ttySn */ 146 /* this is a serial console; assuming it is named /dev/ttySn */
141 sprintf(console + 8, "S%d", u.sr.line); 147 sprintf(console + 8, "S%u", (int)u.sr.line);
142 break; 148 break;
143 } 149 }
144#endif 150#endif
145 /* nope, could not find it */ 151 /* nope, could not find it */
146 goto ret; 152 console[0] = '\0';
147 } while (0); 153 } while (0);
154 }
155
156 argv++;
157 if (!argv[0]) {
158 if (!console[0])
159 return EXIT_FAILURE;
160 puts(console);
161 return EXIT_SUCCESS;
162 }
148 163
164 if (fd < 0) {
149 fd = open_or_warn(console, O_RDWR); 165 fd = open_or_warn(console, O_RDWR);
150 if (fd < 0) 166 if (fd < 0)
151 goto ret; 167 goto ret;
152 //bb_error_msg("switching to '%s'", console);
153 dup2(fd, 0);
154 dup2(fd, 1);
155 dup2(fd, 2);
156 while (fd > 2)
157 close(fd--);
158 /* Some other session may have it as ctty,
159 * steal it from them:
160 */
161 ioctl(0, TIOCSCTTY, 1);
162 } 168 }
163 169 //bb_error_msg("switching to '%s'", console);
164ret: 170 dup2(fd, 0);
171 dup2(fd, 1);
172 dup2(fd, 2);
173 while (fd > 2)
174 close(fd--);
175 /* Some other session may have it as ctty,
176 * try to steal it from them:
177 */
178 ioctl(0, TIOCSCTTY, 1);
179 ret:
165 BB_EXECVP_or_die(argv); 180 BB_EXECVP_or_die(argv);
166} 181}