/* openvt.c - Run a program on a new VT
 *
 * Copyright 2014 Vivek Kumar Bhagat <vivek.bhagat89@gmail.com>
 *
 * No Standard

USE_OPENVT(NEWTOY(openvt, "c#<1>63sw", TOYFLAG_BIN|TOYFLAG_NEEDROOT))
USE_DEALLOCVT(NEWTOY(deallocvt, ">1", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_NEEDROOT))

config OPENVT
  bool "openvt"
  default n
  help
    usage: openvt [-c N] [-sw] [command [command_options]]

    start a program on a new virtual terminal (VT)

    -c N  Use VT N
    -s    Switch to new VT
    -w    Wait for command to exit

    if -sw used together, switch back to originating VT when command completes

config DEALLOCVT
  bool "deallocvt"
  default n
  help
    usage: deallocvt [N]

    Deallocate unused virtual terminal /dev/ttyN, or all unused consoles.
*/

#define FOR_openvt
#include "toys.h"
#include <linux/vt.h>
#include <linux/kd.h>

GLOBALS(
  unsigned long vt_num;
)

int open_console(void)
{
  char arg, *console_name[] = {"/dev/tty", "/dev/tty0", "/dev/console"};
  int i, fd;

  for (i = 0; i < ARRAY_LEN(console_name); i++) {
    fd = open(console_name[i], O_RDWR);
    if (fd >= 0) {
      arg = 0;
      if (!ioctl(fd, KDGKBTYPE, &arg)) return fd;
      close(fd);
    }
  }

  /* check std fd 0, 1 and 2 */
  for (fd = 0; fd < 3; fd++) {
    arg = 0;
    if (0 == ioctl(fd, KDGKBTYPE, &arg)) return fd;
  }

  return -1;
}

int xvtnum(int fd)
{
  int ret;

  ret = ioctl(fd, VT_OPENQRY, (int *)&TT.vt_num);
  if (ret != 0 || TT.vt_num <= 0) perror_exit("can't find open VT");

  return TT.vt_num;
}

void openvt_main(void)
{
  int fd, vt_fd, ret = 0;
  struct vt_stat vstate;
  pid_t pid;

  if (!(toys.optflags & FLAG_c)) {
    // check if fd 0,1 or 2 is already opened
    for (fd = 0; fd < 3; fd++)
      if (!ioctl(fd, VT_GETSTATE, &vstate)) {
        ret = xvtnum(fd);
        break;
      }

    // find VT number using /dev/console
    if (!ret) {
      fd = xopen("/dev/console", O_RDONLY | O_NONBLOCK);
      xioctl(fd, VT_GETSTATE, &vstate);
      xvtnum(fd);
    }
  }

  sprintf(toybuf, "/dev/tty%lu", TT.vt_num);
  fd = open_console();
  xioctl(fd, VT_GETSTATE, &vstate);

  close(0);  //new vt becomes stdin
  vt_fd = xopen(toybuf, O_RDWR);
  if (toys.optflags & FLAG_s) {
    ioctl(vt_fd, VT_ACTIVATE, TT.vt_num);
    ioctl(vt_fd, VT_WAITACTIVE, TT.vt_num);
  }

  close(1);
  close(2);
  dup2(vt_fd, 1);
  dup2(vt_fd, 2);
  while (vt_fd > 2)
    close(vt_fd--);

  pid = xfork();
  if (!pid) {
    setsid();
    ioctl(vt_fd, TIOCSCTTY, 0);
    xexec(toys.optargs);
  }

  if (toys.optflags & FLAG_w) {
    while (-1 == waitpid(pid, NULL, 0) && errno == EINTR)
      ;
    if (toys.optflags & FLAG_s) {
      ioctl(fd, VT_ACTIVATE, vstate.v_active);
      ioctl(fd, VT_WAITACTIVE, vstate.v_active);
      //check why deallocate isn't working here
      xioctl(fd, VT_DISALLOCATE, (void *)(ptrdiff_t)TT.vt_num); 
    }
  }
}

void deallocvt_main(void)
{
  long vt_num = 0; // 0 deallocates all unused consoles
  int fd;

  if (*toys.optargs) vt_num = atolx_range(*toys.optargs, 1, 63);

  if ((fd = open_console()) < 0) error_exit("can't open console");
  xioctl(fd, VT_DISALLOCATE, (void *)vt_num);
  if (CFG_TOYBOX_FREE) close(fd);
}
