master xplshn/aruu / cmd / linux / chvt.c
 1/* See LICENSE file for copyright and license details. */
 2
 3
 4#include <sys/ioctl.h>
 5#include <sys/types.h>
 6
 7#include <fcntl.h>
 8#include <limits.h>
 9#include <stdio.h>
10#include <string.h>
11#include <unistd.h>
12
13#include "util.h"
14
15#define KDGKBTYPE	0x4B33	/* get keyboard type */
16
17#define VT_ACTIVATE	0x5606	/* make vt active */
18#define VT_WAITACTIVE	0x5607	/* wait for vt active */
19
20static char *vt[] = {
21	"/proc/self/fd/0",
22	"/dev/console",
23	"/dev/tty",
24	"/dev/tty0",
25};
26
27static void
28usage(void)
29{
30	eprintf("usage: %s num\n", argv0);
31}
32
33// ?man chvt: change foreground virtual terminal
34// ?man arguments: num
35// ?man change the active virtual terminal
36int
37main(int argc, char *argv[])
38{
39	unsigned int n, i;
40	int fd;
41	char c;
42
43	ARGBEGIN {
44	default:
45		usage();
46	} ARGEND;
47
48	if (argc != 1)
49		usage();
50
51	n = estrtonum(argv[0], 0, UINT_MAX);
52	for (i = 0; i < LEN(vt); i++) {
53		if ((fd = open(vt[i], O_RDONLY)) < 0)
54			continue;
55		c = 0;
56		if (ioctl(fd, KDGKBTYPE, &c) == 0)
57			goto found;
58		if (close(fd) < 0)
59			eprintf("close %s:", vt[i]);
60	}
61	eprintf("no console found\n");
62
63found:
64	if (ioctl(fd, VT_ACTIVATE, n) == -1)
65		eprintf("VT_ACTIVATE %u:", n);
66	if (ioctl(fd, VT_WAITACTIVE, n) == -1)
67		eprintf("VT_WAITACTIVE %u:", n);
68	if (close(fd) < 0)
69		eprintf("close %s:", vt[i]);
70
71	return 0;
72}