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        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