Imported Upstream version 2.0.4
[platform/upstream/kbd.git] / src / libcommon / getfd.c
1 #include "config.h"
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <unistd.h>
6 #include <fcntl.h>
7 #include <errno.h>
8 #include <sys/ioctl.h>
9 #include <linux/kd.h>
10
11 #include "libcommon.h"
12
13 static const char *conspath[] = {
14         "/proc/self/fd/0",
15         "/dev/tty",
16         "/dev/tty0",
17         "/dev/vc/0",
18         "/dev/systty",
19         "/dev/console",
20         NULL
21 };
22
23 /*
24  * getfd.c
25  *
26  * Get an fd for use with kbd/console ioctls.
27  * We try several things because opening /dev/console will fail
28  * if someone else used X (which does a chown on /dev/console).
29  */
30
31 static int
32 is_a_console(int fd)
33 {
34         char arg;
35
36         arg = 0;
37         return (isatty(fd) && ioctl(fd, KDGKBTYPE, &arg) == 0 && ((arg == KB_101) || (arg == KB_84)));
38 }
39
40 static int
41 open_a_console(const char *fnam)
42 {
43         int fd;
44
45         /*
46          * For ioctl purposes we only need some fd and permissions
47          * do not matter. But setfont:activatemap() does a write.
48          */
49         fd = open(fnam, O_RDWR);
50         if (fd < 0)
51                 fd = open(fnam, O_WRONLY);
52         if (fd < 0)
53                 fd = open(fnam, O_RDONLY);
54         if (fd < 0)
55                 return -1;
56         return fd;
57 }
58
59 int
60 getfd(const char *fnam)
61 {
62         int fd, i;
63
64         if (fnam) {
65                 if ((fd = open_a_console(fnam)) >= 0) {
66                         if (is_a_console(fd))
67                                 return fd;
68                         close(fd);
69                 }
70                 fprintf(stderr, _("Couldn't open %s\n"), fnam);
71                 exit(1);
72         }
73
74         for (i = 0; conspath[i]; i++) {
75                 if ((fd = open_a_console(conspath[i])) >= 0) {
76                         if (is_a_console(fd))
77                                 return fd;
78                         close(fd);
79                 }
80         }
81
82         for (fd = 0; fd < 3; fd++)
83                 if (is_a_console(fd))
84                         return fd;
85
86         fprintf(stderr,
87                 _("Couldn't get a file descriptor referring to the console\n"));
88
89         /* total failure */
90         exit(1);
91 }