diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 55 |
1 files changed, 52 insertions, 3 deletions
@@ -20,14 +20,40 @@ struct pollfd pfds[NPFDS] = {0}; +int open_devices[NPFDS] = {0}; int test_mode = 0; uint64_t keys[KEYS_SIZE] = {0}; -void add_device(const char name[static 1]) +int parse_device_name(const char name[static 1], unsigned long *device_id) { if (strncmp(name, "event", strlen("event")) != 0) { + return -1; + } + char *endptr; + *device_id = strtoul(name + strlen("event"), &endptr, 10); + if (*endptr != '\0') + { + return -1; + } + return 0; +} + +void add_device(const char name[static 1]) +{ + unsigned long device_id; + if (parse_device_name(name, &device_id) == -1) + { + return; + } + if (device_id >= NPFDS) + { + fprintf(stderr, "exceeded device limit\n"); + return; + } + if (open_devices[device_id]) + { return; } char path[NAME_MAX + 1 + 11] = "/dev/input/"; /* 11 == strlen("/dev/input/") */ @@ -38,6 +64,7 @@ void add_device(const char name[static 1]) fprintf(stderr, "failed to open device: %s: %s\n", path, strerror(errno)); return; } + open_devices[device_id] = 1; for (size_t i = 1; i < NPFDS; i++) { if (pfds[i].fd < 0) @@ -48,6 +75,20 @@ void add_device(const char name[static 1]) } } +void del_device(const char name[static 1]) +{ + unsigned long device_id; + if (parse_device_name(name, &device_id) == -1) + { + return; + } + if (device_id >= NPFDS) + { + return; + } + open_devices[device_id] = 0; +} + void process_inotify_watch(int inotify_fd) { char buf[sizeof (struct inotify_event) + NAME_MAX + 1] = {0}; @@ -67,7 +108,14 @@ void process_inotify_watch(int inotify_fd) fputs("inotify error (filesystem unmounted?)", stderr); exit(EXIT_FAILURE); } - add_device(event->name); + else if (event->mask & IN_DELETE) + { + del_device(event->name); + } + else + { + add_device(event->name); + } } } @@ -165,7 +213,8 @@ int run(const char *bindings_file_path) fprintf(stderr, "inotify_init1 failed: %s\n", strerror(errno)); return EXIT_FAILURE; } - int watch_fd = inotify_add_watch(inotify_fd, "/dev/input/", IN_CREATE); + int watch_fd = inotify_add_watch(inotify_fd, "/dev/input/", + IN_CREATE | IN_ATTRIB | IN_DELETE); if (watch_fd < 0) { fprintf(stderr, "inotify_add_watch failed: %s\n", strerror(errno)); |