1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45#define FOR_openvt
46#include "toys.h"
47#include <linux/vt.h>
48#include <linux/kd.h>
49
50GLOBALS(
51 long c;
52)
53
54static int open_console(void)
55{
56 char arg = 0, *console_name[] = {"/dev/tty", "/dev/tty0", "/dev/console"};
57 int i, fd;
58
59 for (i = 0; i < ARRAY_LEN(console_name); i++) {
60 if (0>(fd = open(console_name[i], O_RDWR))) continue;
61 if (!ioctl(fd, KDGKBTYPE, &arg)) return fd;
62 close(fd);
63 }
64 for (fd = 0; fd < 3; fd++) if (!ioctl(fd, KDGKBTYPE, &arg)) return fd;
65 error_exit("can't open console");
66}
67
68static int activate(int fd, int cc)
69{
70 return ioctl(fd, VT_ACTIVATE, cc) || ioctl(fd, VT_WAITACTIVE, cc);
71}
72
73void openvt_main(void)
74{
75 struct vt_stat vstate;
76 int fd, cc = (int)TT.c;
77 pid_t pid;
78
79
80 if (-1 == (ioctl(fd = open_console(), VT_GETSTATE, &vstate)) ||
81 (!cc && 0>=(cc = xioctl(fd, VT_OPENQRY, &fd))))
82 perror_exit("can't find open VT");
83
84 sprintf(toybuf, "/dev/tty%d", cc);
85 if (!(pid = XVFORK())) {
86 close(0);
87 dup2(dup2(xopen_stdio(toybuf, O_RDWR), 1), 2);
88 if (FLAG(s)) activate(0, cc);
89 setsid();
90 ioctl(0, TIOCSCTTY, 0);
91 if (fd>2) close(fd);
92 xexec(toys.optargs);
93 }
94 if (FLAG(w)) {
95 while (-1 == waitpid(pid, NULL, 0) && errno == EINTR) errno = 0;
96 if (FLAG(s)) {
97 activate(fd, vstate.v_active);
98 dprintf(2, "%d\n", ioctl(fd, VT_DISALLOCATE, cc));
99 }
100 }
101}
102
103void chvt_main(void)
104{
105 if (activate(open_console(), atoi(*toys.optargs)))
106 perror_exit_raw(*toys.optargs);
107}
108
109void deallocvt_main(void)
110{
111 int fd = open_console(), vt_num = 0;
112
113 if (*toys.optargs) vt_num = atolx_range(*toys.optargs, 1, 63);
114 if (-1 == ioctl(fd, VT_DISALLOCATE, vt_num)) perror_exit("%d", vt_num);
115}
116