nc: use symbolic SHUT_WR instead of literal 1
[oweals/busybox.git] / console-tools / showkey.c
index e7834f702f198d5696303552c37e75122e6827f0..69b785ec6200d3f788a814962d86a268fa95c950 100644 (file)
@@ -7,6 +7,14 @@
  * Licensed under GPLv2, see file LICENSE in this source tree.
  */
 
+//usage:#define showkey_trivial_usage
+//usage:       "[-a | -k | -s]"
+//usage:#define showkey_full_usage "\n\n"
+//usage:       "Show keys pressed\n"
+//usage:     "\n       -a      Display decimal/octal/hex values of the keys"
+//usage:     "\n       -k      Display interpreted keycodes (default)"
+//usage:     "\n       -s      Display raw scan-codes"
+
 #include "libbb.h"
 #include <linux/kd.h>
 
@@ -56,37 +64,45 @@ int showkey_main(int argc UNUSED_PARAM, char **argv)
        // FIXME: aks are all mutually exclusive
        getopt32(argv, "aks");
 
-       // get keyboard settings
-       xioctl(STDIN_FILENO, KDGKBMODE, &kbmode);
-       printf("kb mode was %s\n\nPress any keys. Program terminates %s\n\n",
-               kbmode == K_RAW ? "RAW" :
-                       (kbmode == K_XLATE ? "XLATE" :
-                               (kbmode == K_MEDIUMRAW ? "MEDIUMRAW" :
-                                       (kbmode == K_UNICODE ? "UNICODE" : "UNKNOWN")))
-               , (option_mask32 & OPT_a) ? "on EOF (ctrl-D)" : "10s after last keypress"
-       );
-
        // prepare for raw mode
        xget1(&tio, &tio0);
        // put stdin in raw mode
        xset1(&tio);
 
+#define press_keys "Press any keys, program terminates %s:\r\n\n"
+
        if (option_mask32 & OPT_a) {
+               // just read stdin char by char
                unsigned char c;
 
-               // just read stdin char by char
+               printf(press_keys, "on EOF (ctrl-D)");
+
+               // read and show byte values
                while (1 == read(STDIN_FILENO, &c, 1)) {
                        printf("%3u 0%03o 0x%02x\r\n", c, c, c);
                        if (04 /*CTRL-D*/ == c)
                                break;
                }
+
        } else {
+               // we assume a PC keyboard
+               xioctl(STDIN_FILENO, KDGKBMODE, &kbmode);
+               printf("Keyboard mode was %s.\r\n\n",
+                       kbmode == K_RAW ? "RAW" :
+                               (kbmode == K_XLATE ? "XLATE" :
+                                       (kbmode == K_MEDIUMRAW ? "MEDIUMRAW" :
+                                               (kbmode == K_UNICODE ? "UNICODE" : "UNKNOWN")))
+               );
+
                // set raw keyboard mode
                xioctl(STDIN_FILENO, KDSKBMODE, (void *)(ptrdiff_t)((option_mask32 & OPT_k) ? K_MEDIUMRAW : K_RAW));
 
                // we should exit on any signal; signals should interrupt read
                bb_signals_recursive_norestart(BB_FATAL_SIGS, record_signo);
 
+               // inform user that program ends after time of inactivity
+               printf(press_keys, "10s after last keypress");
+
                // read and show scancodes
                while (!bb_got_signal) {
                        char buf[18];
@@ -94,6 +110,7 @@ int showkey_main(int argc UNUSED_PARAM, char **argv)
 
                        // setup 10s watchdog
                        alarm(10);
+
                        // read scancodes
                        n = read(STDIN_FILENO, buf, sizeof(buf));
                        i = 0;
@@ -121,11 +138,13 @@ int showkey_main(int argc UNUSED_PARAM, char **argv)
                        }
                        puts("\r");
                }
+
+               // restore keyboard mode
+               xioctl(STDIN_FILENO, KDSKBMODE, (void *)(ptrdiff_t)kbmode);
        }
 
-       // restore keyboard and console settings
+       // restore console settings
        xset1(&tio0);
-       xioctl(STDIN_FILENO, KDSKBMODE, (void *)(ptrdiff_t)kbmode);
 
        return EXIT_SUCCESS;
 }