9 #include <linux/input.h>
13 uint16_t key; // bit 15: 0=press, 1=release
16 static void __attribute__((noreturn)) __attribute__((format(printf,1,2))) die(char *fmt, ...)
20 fprintf(stderr, "keyspy: ");
21 vfprintf(stderr, fmt, args);
25 static void record(char *logname)
27 int evfd = open("/dev/input/by-path/platform-i8042-serio-0-event-kbd", O_RDONLY);
29 die("Cannot open event device: %m\n");
31 int spyfd = open(logname, O_WRONLY | O_CREAT | O_APPEND, 0600);
33 die("Cannot open spy log %s: %m\n", logname);
38 struct input_event ev;
39 if (read(evfd, &ev, sizeof(ev)) != sizeof(ev))
40 die("Error reading event device: %m\n");
41 printf("type=%04x code=%04x value=%08x\n", ev.type, ev.code, ev.value);
42 if (ev.type == EV_KEY)
45 int64_t t = (uint64_t) ev.time.tv_sec * 1000 + ev.time.tv_usec / 1000;
46 int64_t dt = t - last_t;
53 se.key = (ev.code < 0x8000 ? ev.code : 0x7fff);
56 if (write(spyfd, &se, sizeof(se)) != sizeof(se))
57 die("Error writing spy log: %m\n");
62 const char *key_names[] = {
66 static void show(char *logname)
68 FILE *f = fopen(logname, "r");
70 die("Cannot read log: %m\n");
72 while (fread(&se, sizeof(se), 1, f))
74 if (se.delta_ms == 0xffff)
77 printf("%5d ", se.delta_ms);
78 printf("%c ", (se.key & 0x8000 ? '-' : '+'));
79 unsigned k = se.key & 0x7fff;
80 if (k < sizeof(key_names) / sizeof(key_names[0]) && key_names[k])
81 printf("%s\n", key_names[k]);
87 static void usage(void)
90 Usage: keyspy record <logfile>\n\
91 or: keyspy show <logfile>\n\
96 int main(int argc, char **argv)
100 if (!strcmp(argv[1], "record"))
102 else if (!strcmp(argv[1], "show"))