1/* This code is adapted from busybox project 2 * 3 * Licensed under GPLv2 4 */ 5#include "libbb.h" 6 7/* From <linux/vt.h> */ 8struct vt_stat { 9 unsigned short v_active; /* active vt */ 10 unsigned short v_signal; /* signal to send */ 11 unsigned short v_state; /* vt bitmask */ 12}; 13enum { VT_GETSTATE = 0x5603 }; /* get global vt state info */ 14 15/* From <linux/serial.h> */ 16struct serial_struct { 17 int type; 18 int line; 19 unsigned int port; 20 int irq; 21 int flags; 22 int xmit_fifo_size; 23 int custom_divisor; 24 int baud_base; 25 unsigned short close_delay; 26 char io_type; 27 char reserved_char[1]; 28 int hub6; 29 unsigned short closing_wait; /* time to wait before closing */ 30 unsigned short closing_wait2; /* no longer used... */ 31 unsigned char *iomem_base; 32 unsigned short iomem_reg_shift; 33 unsigned int port_high; 34 unsigned long iomap_base; /* cookie passed into ioremap */ 35 int reserved[1]; 36}; 37 38int cttyhack_main(int argc, char **argv) ATTRIBUTE_NORETURN; 39int cttyhack_main(int argc, char **argv) 40{ 41 int fd; 42 char console[sizeof(int)*3 + 16]; 43 union { 44 struct vt_stat vt; 45 struct serial_struct sr; 46 char paranoia[sizeof(struct serial_struct) * 3]; 47 } u; 48 49 if (!*++argv) { 50 bb_show_usage(); 51 } 52 53 strcpy(console, "/dev/tty"); 54 if (ioctl(0, TIOCGSERIAL, &u.sr) == 0) { 55 /* this is a serial console */ 56 sprintf(console + 8, "S%d", u.sr.line); 57 } else if (ioctl(0, VT_GETSTATE, &u.vt) == 0) { 58 /* this is linux virtual tty */ 59 sprintf(console + 8, "S%d" + 1, u.vt.v_active); 60 } 61 62 if (console[8]) { 63 fd = xopen(console, O_RDWR); 64 //bb_error_msg("switching to '%s'", console); 65 dup2(fd, 0); 66 dup2(fd, 1); 67 dup2(fd, 2); 68 while (fd > 2) close(fd--); 69 } 70 71 execvp(argv[0], argv); 72 bb_perror_msg_and_die("cannot exec '%s'", argv[0]); 73} 74