master xplshn/aruu / cmd / linux / chvt.c
 1/* See LICENSE file for copyright and license details. */
 2
 3#include <sys/ioctl.h>
 4#include <sys/types.h>
 5
 6#include <fcntl.h>
 7#include <limits.h>
 8#include <stdio.h>
 9#include <string.h>
10#include <unistd.h>
11
12#include "paths.h"
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    ARUU_LINUX_PATH_PROC "/self/fd/0",
22    ARUU_PATH_DEVCONSOLE,
23    ARUU_PATH_DEVTTY,
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  {
45    default:
46      usage();
47  }
48  ARGEND;
49
50  if (argc != 1)
51    usage();
52
53  n = estrtonum(argv[0], 0, UINT_MAX);
54  for (i = 0; i < LEN(vt); i++) {
55    if ((fd = open(vt[i], O_RDONLY)) < 0)
56      continue;
57    c = 0;
58    if (ioctl(fd, KDGKBTYPE, &c) == 0)
59      goto found;
60    if (close(fd) < 0)
61      eprintf("close %s:", vt[i]);
62  }
63  eprintf("no console found\n");
64
65found:
66  if (ioctl(fd, VT_ACTIVATE, n) == -1)
67    eprintf("VT_ACTIVATE %u:", n);
68  if (ioctl(fd, VT_WAITACTIVE, n) == -1)
69    eprintf("VT_WAITACTIVE %u:", n);
70  if (close(fd) < 0)
71    eprintf("close %s:", vt[i]);
72
73  return 0;
74}