diff options
Diffstat (limited to 'console-tools/kbd_mode.c')
-rw-r--r-- | console-tools/kbd_mode.c | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/console-tools/kbd_mode.c b/console-tools/kbd_mode.c index d81c56e92..f16449dcd 100644 --- a/console-tools/kbd_mode.c +++ b/console-tools/kbd_mode.c | |||
@@ -15,19 +15,19 @@ | |||
15 | //config: help | 15 | //config: help |
16 | //config: This program reports and sets keyboard mode. | 16 | //config: This program reports and sets keyboard mode. |
17 | 17 | ||
18 | //applet:IF_KBD_MODE(APPLET(kbd_mode, BB_DIR_BIN, BB_SUID_DROP)) | 18 | //applet:IF_KBD_MODE(APPLET_NOEXEC(kbd_mode, kbd_mode, BB_DIR_BIN, BB_SUID_DROP, kbd_mode)) |
19 | 19 | ||
20 | //kbuild:lib-$(CONFIG_KBD_MODE) += kbd_mode.o | 20 | //kbuild:lib-$(CONFIG_KBD_MODE) += kbd_mode.o |
21 | 21 | ||
22 | //usage:#define kbd_mode_trivial_usage | 22 | //usage:#define kbd_mode_trivial_usage |
23 | //usage: "[-a|k|s|u] [-C TTY]" | 23 | //usage: "[-a|k|s|u] [-C TTY]" |
24 | //usage:#define kbd_mode_full_usage "\n\n" | 24 | //usage:#define kbd_mode_full_usage "\n\n" |
25 | //usage: "Report or set the keyboard mode\n" | 25 | //usage: "Report or set VT console keyboard mode\n" |
26 | //usage: "\n -a Default (ASCII)" | 26 | //usage: "\n -a Default (ASCII)" |
27 | //usage: "\n -k Medium-raw (keyboard)" | 27 | //usage: "\n -k Medium-raw (keycode)" |
28 | //usage: "\n -s Raw (scancode)" | 28 | //usage: "\n -s Raw (scancode)" |
29 | //usage: "\n -u Unicode (utf-8)" | 29 | //usage: "\n -u Unicode (utf-8)" |
30 | //usage: "\n -C TTY Affect TTY instead of /dev/tty" | 30 | //usage: "\n -C TTY Affect TTY" |
31 | 31 | ||
32 | #include "libbb.h" | 32 | #include "libbb.h" |
33 | #include <linux/kd.h> | 33 | #include <linux/kd.h> |
@@ -43,11 +43,20 @@ int kbd_mode_main(int argc UNUSED_PARAM, char **argv) | |||
43 | }; | 43 | }; |
44 | int fd; | 44 | int fd; |
45 | unsigned opt; | 45 | unsigned opt; |
46 | const char *tty_name = CURRENT_TTY; | 46 | const char *tty_name; |
47 | 47 | ||
48 | opt = getopt32(argv, "sakuC:", &tty_name); | 48 | opt = getopt32(argv, "sakuC:", &tty_name); |
49 | fd = xopen_nonblocking(tty_name); | 49 | if (opt & 0x10) { |
50 | opt &= 0xf; /* clear -C bit, see (*) */ | 50 | opt &= 0xf; /* clear -C bit, see (*) */ |
51 | fd = xopen_nonblocking(tty_name); | ||
52 | } else { | ||
53 | /* kbd-2.0.3 tries in sequence: | ||
54 | * fd#0, /dev/tty, /dev/tty0. | ||
55 | * get_console_fd_or_die: /dev/console, /dev/tty0, /dev/tty. | ||
56 | * kbd-2.0.3 checks KDGKBTYPE, get_console_fd_or_die checks too. | ||
57 | */ | ||
58 | fd = get_console_fd_or_die(); | ||
59 | } | ||
51 | 60 | ||
52 | if (!opt) { /* print current setting */ | 61 | if (!opt) { /* print current setting */ |
53 | const char *mode = "unknown"; | 62 | const char *mode = "unknown"; |
@@ -62,9 +71,19 @@ int kbd_mode_main(int argc UNUSED_PARAM, char **argv) | |||
62 | mode = "mediumraw (keycode)"; | 71 | mode = "mediumraw (keycode)"; |
63 | else if (m == K_UNICODE) | 72 | else if (m == K_UNICODE) |
64 | mode = "Unicode (UTF-8)"; | 73 | mode = "Unicode (UTF-8)"; |
74 | else if (m == 4 /*K_OFF*/) /* kbd-2.0.3 does not show this mode, says "unknown" */ | ||
75 | mode = "off"; | ||
65 | printf("The keyboard is in %s mode\n", mode); | 76 | printf("The keyboard is in %s mode\n", mode); |
66 | } else { | 77 | } else { |
67 | /* here we depend on specific bits assigned to options (*) */ | 78 | /* here we depend on specific bits assigned to options (*) |
79 | * KDSKBMODE constants have these values: | ||
80 | * #define K_RAW 0x00 | ||
81 | * #define K_XLATE 0x01 | ||
82 | * #define K_MEDIUMRAW 0x02 | ||
83 | * #define K_UNICODE 0x03 | ||
84 | * #define K_OFF 0x04 | ||
85 | * (looks like "-ak" together would cause the same effect as -u) | ||
86 | */ | ||
68 | opt = opt & UNICODE ? 3 : opt >> 1; | 87 | opt = opt & UNICODE ? 3 : opt >> 1; |
69 | /* double cast prevents warnings about widening conversion */ | 88 | /* double cast prevents warnings about widening conversion */ |
70 | xioctl(fd, KDSKBMODE, (void*)(ptrdiff_t)opt); | 89 | xioctl(fd, KDSKBMODE, (void*)(ptrdiff_t)opt); |