File: vt.c

package info (click to toggle)
uswsusp 1.0+20120915-6.2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 1,572 kB
  • sloc: ansic: 7,164; sh: 566; makefile: 223; perl: 65
file content (133 lines) | stat: -rw-r--r-- 2,200 bytes parent folder | download | duplicates (4)
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 <seife@suse.de>
 */

#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;
}