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:
parent
bcdae63875
commit
156840c249
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user