-
Notifications
You must be signed in to change notification settings - Fork 4
/
vt.c
133 lines (113 loc) · 2.15 KB
/
vt.c
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/* vt.c - VT specific routines
* most of these are simplified versions of routines that can
* be found in the kbd package.
*
* Released under GPL V2.
* (C) 2006 Stefan Seyfried <[email protected]>
*/
#include "config.h"
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/kd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <linux/vt.h>
int is_a_console(int fd)
{
char arg;
arg = 0;
return (ioctl(fd, KDGKBTYPE, &arg) == 0
&& ((arg == KB_101) || (arg == KB_84)));
}
int open_a_console(const char *fnam)
{
int fd;
fd = open(fnam, O_RDWR);
if (fd < 0)
return -1;
if (!is_a_console(fd)) {
close(fd);
return -1;
}
return fd;
}
int getconsolefd(void)
{
int fd;
fd = open_a_console("/dev/tty");
if (fd >= 0)
return fd;
fd = open_a_console("/dev/tty0");
if (fd >= 0)
return fd;
fd = open_a_console("/dev/vc/0");
if (fd >= 0)
return fd;
fd = open_a_console("/dev/console");
if (fd >= 0)
return fd;
for (fd = 0; fd < 3; fd++)
if (is_a_console(fd))
return fd;
return -1;
}
int fgconsole(void)
{
int fd;
struct vt_stat vtstat;
fd = getconsolefd();
if (fd < 0) {
perror("fgconsole: getconsolefd");
return -1;
}
if (ioctl(fd, VT_GETSTATE, &vtstat)) {
perror("fgconsole: VT_GETSTATE");
return -1;
}
return vtstat.v_active;
}
int chvt(int num)
{
#define USER_WAIT_SLEEP_US 100000
#define USER_WAIT_MAX_ITERATIONS 50
int i, fd, active = 0;
for (i = 0; i < USER_WAIT_MAX_ITERATIONS; i++) {
if (fgconsole() == num) {
active = 1;
break;
}
fd = getconsolefd();
if (ioctl(fd, VT_ACTIVATE, num)) {
perror("chvt: VT_ACTIVATE");
}
usleep(USER_WAIT_SLEEP_US);
}
return active;
}
int is_framebuffer(void)
{
return !access("/sys/class/graphics/fb0", F_OK);
}
char *get_fbname(void)
{
int fd, len;
/* id of the driver can be 16bytes long + cr appended by sysfs */
char *id = malloc(17);
fd = open("/sys/class/graphics/fb0/name", O_RDONLY);
if (fd < 0) {
strcpy(id, "error");
goto out;
}
len = read(fd, id, 17);
if (len <= 0)
strcpy(id, "error");
else
/* strip the cr appended by sysfs */
id[len-1] = '\0';
close(fd);
out:
return id;
}