cttyhack: print detected ctty name when called without parameters

Sometimes there's a need to figure out the controlling tty from a shell
script, for example, to obtain a line for getty. In this case it's easier
to call cttyhack than trying to repeat some of the cttyhack's logic.

function                                             old     new   delta
cttyhack_main                                        283     327     +44
packed_usage                                       28911   28915      +4

Signed-off-by: Alexander Shishkin <virtuoso@slind.org>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Alexander Shishkin 2011-10-31 13:18:44 +01:00 committed by Denys Vlasenko
parent bcdae63875
commit 156840c249

View File

@ -50,9 +50,12 @@
//config: //config:
//config: # exec setsid sh -c 'exec sh </dev/tty1 >/dev/tty1 2>&1' //config: # exec setsid sh -c 'exec sh </dev/tty1 >/dev/tty1 2>&1'
//config: //config:
//config: Starting getty on a controlling tty from a shell script:
//config:
//config: # getty 115200 $(cttyhack)
//usage:#define cttyhack_trivial_usage //usage:#define cttyhack_trivial_usage
//usage: "PROG ARGS" //usage: "[PROG ARGS]"
//usage:#define cttyhack_full_usage "\n\n" //usage:#define cttyhack_full_usage "\n\n"
//usage: "Give PROG a controlling tty if possible." //usage: "Give PROG a controlling tty if possible."
//usage: "\nExample for /etc/inittab (for busybox init):" //usage: "\nExample for /etc/inittab (for busybox init):"
@ -108,20 +111,29 @@ int cttyhack_main(int argc UNUSED_PARAM, char **argv)
char paranoia[sizeof(struct serial_struct) * 3]; char paranoia[sizeof(struct serial_struct) * 3];
} u; } u;
if (!*++argv) {
bb_show_usage();
}
strcpy(console, "/dev/tty"); strcpy(console, "/dev/tty");
fd = open(console, O_RDWR); fd = open(console, O_RDWR);
if (fd >= 0) { if (fd < 0) {
/* We already have ctty, nothing to do */
close(fd);
} else {
/* We don't have ctty (or don't have "/dev/tty" node...) */ /* We don't have ctty (or don't have "/dev/tty" node...) */
do { do {
#ifdef __linux__ #ifdef __linux__
int s = open_read_close("/sys/class/tty/console/active", int s;
if (ioctl(0, VT_GETSTATE, &u.vt) == 0) {
/* this is linux virtual tty */
sprintf(console + 8, "S%u" + 1, (int)u.vt.v_active);
break;
}
#endif
#ifdef TIOCGSERIAL
if (ioctl(0, TIOCGSERIAL, &u.sr) == 0) {
/* this is a serial console; assuming it is named /dev/ttySn */
sprintf(console + 8, "S%u", (int)u.sr.line);
break;
}
#endif
#ifdef __linux__
/* Note that this method is not related to _stdin_ */
s = open_read_close("/sys/class/tty/console/active",
console + 5, sizeof(console) - 5); console + 5, sizeof(console) - 5);
if (s > 0) { if (s > 0) {
/* found active console via sysfs (Linux 2.6.38+) /* found active console via sysfs (Linux 2.6.38+)
@ -130,39 +142,35 @@ int cttyhack_main(int argc UNUSED_PARAM, char **argv)
console[4 + s] = '\0'; console[4 + s] = '\0';
break; break;
} }
if (ioctl(0, VT_GETSTATE, &u.vt) == 0) {
/* this is linux virtual tty */
sprintf(console + 8, "S%d" + 1, u.vt.v_active);
break;
}
#endif
#ifdef TIOCGSERIAL
if (ioctl(0, TIOCGSERIAL, &u.sr) == 0) {
/* this is a serial console; assuming it is named /dev/ttySn */
sprintf(console + 8, "S%d", u.sr.line);
break;
}
#endif #endif
/* nope, could not find it */ /* nope, could not find it */
goto ret; console[0] = '\0';
} while (0); } while (0);
}
argv++;
if (!argv[0]) {
if (!console[0])
return EXIT_FAILURE;
puts(console);
return EXIT_SUCCESS;
}
if (fd < 0) {
fd = open_or_warn(console, O_RDWR); fd = open_or_warn(console, O_RDWR);
if (fd < 0) if (fd < 0)
goto ret; goto ret;
//bb_error_msg("switching to '%s'", console);
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, 2);
while (fd > 2)
close(fd--);
/* Some other session may have it as ctty,
* steal it from them:
*/
ioctl(0, TIOCSCTTY, 1);
} }
//bb_error_msg("switching to '%s'", console);
ret: dup2(fd, 0);
dup2(fd, 1);
dup2(fd, 2);
while (fd > 2)
close(fd--);
/* Some other session may have it as ctty,
* try to steal it from them:
*/
ioctl(0, TIOCSCTTY, 1);
ret:
BB_EXECVP_or_die(argv); BB_EXECVP_or_die(argv);
} }