busybox/shell/cttyhack.c
<<
>>
Prefs
   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        if (ioctl(0, TIOCGSERIAL, &u.sr) == 0) {
  57                /* this is a serial console */
  58                sprintf(console + 8, "S%d", u.sr.line);
  59        } else if (ioctl(0, VT_GETSTATE, &u.vt) == 0) {
  60                /* this is linux virtual tty */
  61                sprintf(console + 8, "S%d" + 1, u.vt.v_active);
  62        }
  63
  64        if (console[8]) {
  65                fd = xopen(console, O_RDWR);
  66                //bb_error_msg("switching to '%s'", console);
  67                dup2(fd, 0);
  68                dup2(fd, 1);
  69                dup2(fd, 2);
  70                while (fd > 2) close(fd--);
  71                /* Some other session may have it as ctty. Steal it from them */
  72                ioctl(0, TIOCSCTTY, 1);
  73        }
  74
  75        BB_EXECVP(argv[0], argv);
  76        bb_perror_msg_and_die("can't execute '%s'", argv[0]);
  77}
  78