1/* vi: set sw=4 ts=4: */ 2/* 3 * Licensed under GPLv2 4 * 5 * Copyright (c) 2007 Denys Vlasenko <vda.linux@googlemail.com> 6 */ 7#include "libbb.h" 8 9/* From <linux/vt.h> */ 10struct vt_stat { 11 unsigned short v_active; /* active vt */ 12 unsigned short v_signal; /* signal to send */ 13 unsigned short v_state; /* vt bitmask */ 14}; 15enum { VT_GETSTATE = 0x5603 }; /* get global vt state info */ 16 17/* From <linux/serial.h> */ 18struct serial_struct { 19 int type; 20 int line; 21 unsigned int port; 22 int irq; 23 int flags; 24 int xmit_fifo_size; 25 int custom_divisor; 26 int baud_base; 27 unsigned short close_delay; 28 char io_type; 29 char reserved_char[1]; 30 int hub6; 31 unsigned short closing_wait; /* time to wait before closing */ 32 unsigned short closing_wait2; /* no longer used... */ 33 unsigned char *iomem_base; 34 unsigned short iomem_reg_shift; 35 unsigned int port_high; 36 unsigned long iomap_base; /* cookie passed into ioremap */ 37 int reserved[1]; 38}; 39 40int cttyhack_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 41int cttyhack_main(int argc UNUSED_PARAM, char **argv) 42{ 43 int fd; 44 char console[sizeof(int)*3 + 16]; 45 union { 46 struct vt_stat vt; 47 struct serial_struct sr; 48 char paranoia[sizeof(struct serial_struct) * 3]; 49 } u; 50 51 if (!*++argv) { 52 bb_show_usage(); 53 } 54 55 strcpy(console, "/dev/tty"); 56 fd = open(console, O_RDWR); 57 if (fd >= 0) { 58 /* We already have ctty, nothing to do */ 59 close(fd); 60 } else { 61 /* We don't have ctty (or don't have "/dev/tty" node...) */ 62 if (ioctl(0, TIOCGSERIAL, &u.sr) == 0) { 63 /* this is a serial console */ 64 sprintf(console + 8, "S%d", u.sr.line); 65 } else if (ioctl(0, VT_GETSTATE, &u.vt) == 0) { 66 /* this is linux virtual tty */ 67 sprintf(console + 8, "S%d" + 1, u.vt.v_active); 68 } 69 if (console[8]) { 70 fd = xopen(console, O_RDWR); 71 //bb_error_msg("switching to '%s'", console); 72 dup2(fd, 0); 73 dup2(fd, 1); 74 dup2(fd, 2); 75 while (fd > 2) 76 close(fd--); 77 /* Some other session may have it as ctty, 78 * steal it from them: 79 */ 80 ioctl(0, TIOCSCTTY, 1); 81 } 82 } 83 84 BB_EXECVP_or_die(argv); 85} 86