Added debian/ from 1:1.10.2-1 debian package
[busybox4maemo] / 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 <sys/ioctl.h>
12 #include "libbb.h"
13
14
15 /* From <linux/kd.h> */
16 enum { KDGKBTYPE = 0x4B33 };  /* get keyboard type */
17
18
19 static int open_a_console(const char *fnam)
20 {
21         int fd;
22
23         /* try read-write */
24         fd = open(fnam, O_RDWR);
25
26         /* if failed, try read-only */
27         if (fd < 0 && errno == EACCES)
28                 fd = open(fnam, O_RDONLY);
29
30         /* if failed, try write-only */
31         if (fd < 0 && errno == EACCES)
32                 fd = open(fnam, O_WRONLY);
33
34         return fd;
35 }
36
37 /*
38  * Get an fd for use with kbd/console ioctls.
39  * We try several things because opening /dev/console will fail
40  * if someone else used X (which does a chown on /dev/console).
41  */
42
43 int get_console_fd(void)
44 {
45         static const char *const console_names[] = {
46                 DEV_CONSOLE, CURRENT_VC, CURRENT_TTY
47         };
48
49         int fd;
50
51         for (fd = 2; fd >= 0; fd--) {
52                 int fd4name;
53                 int choice_fd;
54                 char arg;
55
56                 fd4name = open_a_console(console_names[fd]);
57  chk_std:
58                 choice_fd = (fd4name >= 0 ? fd4name : fd);
59
60                 arg = 0;
61                 if (ioctl(choice_fd, KDGKBTYPE, &arg) == 0)
62                         return choice_fd;
63                 if (fd4name >= 0) {
64                         close(fd4name);
65                         fd4name = -1;
66                         goto chk_std;
67                 }
68         }
69
70         bb_error_msg("can't open console");
71         return fd;                      /* total failure */
72 }