]> git.scottworley.com Git - keystroke-timestamps/blob - keystroke-timestamps.c
36d1cfcd1a24390e128c4627ffabf5c0f95d18ba
[keystroke-timestamps] / keystroke-timestamps.c
1 #include <err.h>
2 #include <fcntl.h>
3 #include <glob.h>
4 #include <getopt.h>
5 #include <linux/input.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <sysexits.h>
10 #include <sys/select.h>
11 #include <unistd.h>
12
13 int main (int argc, char **argv)
14 {
15 int print_usec = 0;
16 char* device = strdup("/dev/input/by-path/*kbd*");
17 struct option long_options[] = {
18 {"device", required_argument, 0, 'd' },
19 {"usec", no_argument, &print_usec, 1 },
20 {0, 0, 0, 0 },
21 };
22 while (1) {
23 int c = getopt_long(argc, argv, "", long_options, NULL);
24 if (c == -1) break;
25 if (c == 'd') {
26 free(device);
27 device = strdup(optarg);
28 continue;
29 }
30 if (c != 0) exit(EX_USAGE);
31 }
32
33 fd_set all_inputs;
34 FD_ZERO(&all_inputs);
35 int maxfd = 0;
36 glob_t glob_result;
37 int glob_return = glob(device, GLOB_ERR | GLOB_NOSORT, NULL, &glob_result);
38 if (glob_return == GLOB_NOMATCH) {
39 errx(EX_NOINPUT, "Could not find keyboard event file(s): %s", device);
40 }
41 if (glob_return != 0) {
42 err(EX_NOINPUT, "Could not glob keyboard event file(s): %s", device);
43 }
44 free(device);
45 for (unsigned i = 0; i < glob_result.gl_pathc; i++) {
46 int open_fd = open(glob_result.gl_pathv[i], O_RDONLY);
47 if (open_fd < 0) {
48 err(EX_NOINPUT, "Could not open keyboard event file: %s", glob_result.gl_pathv[i]);
49 }
50 if (open_fd > maxfd) {
51 maxfd = open_fd;
52 }
53 FD_SET(open_fd, &all_inputs);
54 }
55 globfree(&glob_result);
56
57 struct input_event i;
58 while (1) {
59 fd_set ready_inputs = all_inputs;
60 if (select(maxfd+1, &ready_inputs, NULL, NULL, NULL) != 1) {
61 err(EX_IOERR, "select");
62 }
63 for (int fd=0; fd <= maxfd; fd++) {
64 if (FD_ISSET(fd, &ready_inputs)) {
65 int read_return = read(fd, &i, sizeof(i));
66 if (read_return == -1) {
67 err(EX_IOERR, "read");
68 }
69 if (read_return != sizeof(i)) {
70 errx(EX_IOERR, "Unexpected EOF");
71 }
72 if (i.type == 1 && i.value == 1) {
73 if (print_usec) {
74 printf("%ld.%06ld\n", i.time.tv_sec, i.time.tv_usec);
75 } else {
76 printf("%ld\n", i.time.tv_sec);
77 }
78 fflush(stdout);
79 }
80 }
81 }
82 }
83 return 0;
84 }