1 /* openvt.c - Run a program on a new VT
3 * Copyright 2014 Vivek Kumar Bhagat <vivek.bhagat89@gmail.com>
7 USE_OPENVT(NEWTOY(openvt, "c#<1>63sw", TOYFLAG_BIN|TOYFLAG_NEEDROOT))
8 USE_DEALLOCVT(NEWTOY(deallocvt, ">1", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_NEEDROOT))
13 depends on TOYBOX_FORK
15 usage: openvt [-c N] [-sw] [command [command_options]]
17 start a program on a new virtual terminal (VT)
21 -w Wait for command to exit
23 if -sw used together, switch back to originating VT when command completes
31 Deallocate unused virtual terminal /dev/ttyN, or all unused consoles.
43 int open_console(void)
45 char arg, *console_name[] = {"/dev/tty", "/dev/tty0", "/dev/console"};
48 for (i = 0; i < ARRAY_LEN(console_name); i++) {
49 fd = open(console_name[i], O_RDWR);
52 if (!ioctl(fd, KDGKBTYPE, &arg)) return fd;
57 /* check std fd 0, 1 and 2 */
58 for (fd = 0; fd < 3; fd++) {
60 if (0 == ioctl(fd, KDGKBTYPE, &arg)) return fd;
70 ret = ioctl(fd, VT_OPENQRY, (int *)&TT.vt_num);
71 if (ret != 0 || TT.vt_num <= 0) perror_exit("can't find open VT");
76 void openvt_main(void)
78 int fd, vt_fd, ret = 0;
79 struct vt_stat vstate;
82 if (!(toys.optflags & FLAG_c)) {
83 // check if fd 0,1 or 2 is already opened
84 for (fd = 0; fd < 3; fd++)
85 if (!ioctl(fd, VT_GETSTATE, &vstate)) {
90 // find VT number using /dev/console
92 fd = xopen("/dev/console", O_RDONLY | O_NONBLOCK);
93 xioctl(fd, VT_GETSTATE, &vstate);
98 sprintf(toybuf, "/dev/tty%lu", TT.vt_num);
100 xioctl(fd, VT_GETSTATE, &vstate);
102 close(0); //new vt becomes stdin
103 vt_fd = xopen_stdio(toybuf, O_RDWR);
104 if (toys.optflags & FLAG_s) {
105 ioctl(vt_fd, VT_ACTIVATE, TT.vt_num);
106 ioctl(vt_fd, VT_WAITACTIVE, TT.vt_num);
119 ioctl(vt_fd, TIOCSCTTY, 0);
123 if (toys.optflags & FLAG_w) {
124 while (-1 == waitpid(pid, NULL, 0) && errno == EINTR)
126 if (toys.optflags & FLAG_s) {
127 ioctl(fd, VT_ACTIVATE, vstate.v_active);
128 ioctl(fd, VT_WAITACTIVE, vstate.v_active);
129 //check why deallocate isn't working here
130 xioctl(fd, VT_DISALLOCATE, (void *)(ptrdiff_t)TT.vt_num);
135 void deallocvt_main(void)
137 long vt_num = 0; // 0 deallocates all unused consoles
140 if (*toys.optargs) vt_num = atolx_range(*toys.optargs, 1, 63);
142 if ((fd = open_console()) < 0) error_exit("can't open console");
143 xioctl(fd, VT_DISALLOCATE, (void *)vt_num);
144 if (CFG_TOYBOX_FREE) close(fd);