summaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
authorpapush!2025-07-04 23:58:36 +0200
committerpapush!2025-07-04 23:59:53 +0200
commit4b740d5c8cff9591c666476cc0d3aef0cb637e62 (patch)
treea34793da8f5c54228fff8814fa8288bf4e126901 /src/main.c
parent0d1f4776521b286cb7c0091ac5bcd659cdc87132 (diff)
support hotplugging when udev rules are used to change device permsHEADmaster
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c55
1 files changed, 52 insertions, 3 deletions
diff --git a/src/main.c b/src/main.c
index 00c6eb2..63b6c3d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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));