Replace current verbose GPL stuff in libbb/*.c with one-line GPL boilerplate.
[oweals/busybox.git] / libbb / get_console.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * Utility routines.
4  *
5  * Copyright (C) many different people.  If you wrote this, please
6  * acknowledge your work.
7  *
8  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
9  */
10
11 #include <stdio.h>
12 #include <errno.h>
13 #include <fcntl.h>
14 #include <unistd.h>
15 #include <sys/ioctl.h>
16 #include "libbb.h"
17
18
19
20 /* From <linux/kd.h> */
21 enum { KDGKBTYPE = 0x4B33 };  /* get keyboard type */
22
23
24 static int open_a_console(const char *fnam)
25 {
26         int fd;
27
28         /* try read-write */
29         fd = open(fnam, O_RDWR);
30
31         /* if failed, try read-only */
32         if (fd < 0 && errno == EACCES)
33                 fd = open(fnam, O_RDONLY);
34
35         /* if failed, try write-only */
36         if (fd < 0 && errno == EACCES)
37                 fd = open(fnam, O_WRONLY);
38
39         return fd;
40 }
41
42 /*
43  * Get an fd for use with kbd/console ioctls.
44  * We try several things because opening /dev/console will fail
45  * if someone else used X (which does a chown on /dev/console).
46  */
47
48 int get_console_fd(void)
49 {
50         int fd;
51
52         static const char * const choise_console_names[] = {
53                 CONSOLE_DEV, CURRENT_VC, CURRENT_TTY
54         };
55
56         for (fd = 2; fd >= 0; fd--) {
57                 int fd4name;
58                 int choise_fd;
59                 char arg;
60
61                 fd4name = open_a_console(choise_console_names[fd]);
62         chk_std:
63                 choise_fd = fd4name >= 0 ? fd4name : fd;
64
65                 arg = 0;
66                 if (ioctl(choise_fd, KDGKBTYPE, &arg) == 0)
67                         return choise_fd;
68                 if(fd4name >= 0) {
69                         close(fd4name);
70                         fd4name = -1;
71                         goto chk_std;
72                 }
73         }
74
75         bb_error_msg("Couldn't get a file descriptor referring to the console");
76         return fd;                      /* total failure */
77 }