From 56bd57b5582ea4bbf3cf6f1a50457e64a4e295e8 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Sat, 30 Jul 2022 17:00:08 +0200 Subject: Minor improvements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- libgamepad_list_superdevices.c | 48 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) (limited to 'libgamepad_list_superdevices.c') diff --git a/libgamepad_list_superdevices.c b/libgamepad_list_superdevices.c index f8c7c4d..57068cb 100644 --- a/libgamepad_list_superdevices.c +++ b/libgamepad_list_superdevices.c @@ -5,7 +5,9 @@ int libgamepad_list_superdevices(char ***devicesp, size_t *ndevicesp) { - char path[PATH_MAX], target[PATH_MAX]; /* TODO do not use PATH_MAX */ + char *path, *target; + size_t path_size, target_size = 256; + const size_t path_size_base = sizeof("/sys/class/input//device/device"); int dirfd; DIR *dir; struct dirent *f; @@ -28,18 +30,48 @@ libgamepad_list_superdevices(char ***devicesp, size_t *ndevicesp) return -1; } + path_size = path_size_base + 255; + path_size = path_size > sizeof("/dev/fd/") + 3 * sizeof(int) ? path_size : sizeof("/dev/fd/") + 3 * sizeof(int); + path = malloc(path_size); + if (!path) + goto fail; + + target = malloc(target_size); + if (!target) + goto fail; + while (errno = 0, (f = readdir(dir))) { if (!strncmp(f->d_name, "event", 5) && isdigit(f->d_name[5])) { + if (path_size_base + strlen(f->d_name) > path_size) { + path_size = path_size_base + strlen(f->d_name); + new = realloc(path, path_size); + if (!new) + goto fail; + path = new; + } stpcpy(stpcpy(stpcpy(path, "/sys/class/input/"), f->d_name), "/device/device"); dirfd = open(path, O_PATH); if (dirfd < 0) continue; + sprintf(path, "/dev/fd/%i", dirfd); - r = readlink(path, target, sizeof(target) - 1); - close(dirfd); - if (r < 0) - continue; - target[r] = '\0'; + for (;;) { + r = readlink(path, target, target_size); + if (r < 0) { + close(dirfd); + goto next; + } + if ((size_t)r < target_size) { + close(dirfd); + target[r] = '\0'; + break; + } + new = realloc(target, target_size += 256); + if (!new) + goto fail; + target = new; + } + if (paths) for (i = 0; i < n; i++) if (!strcmp(paths[i], target)) @@ -61,6 +93,8 @@ libgamepad_list_superdevices(char ***devicesp, size_t *ndevicesp) if (errno) goto fail; + free(path); + free(target); closedir(dir); errno = saved_errno; @@ -72,6 +106,8 @@ fail: for (i = 0; i < n; i++) free(paths[i]); free(paths); + free(path); + free(target); closedir(dir); return -1; } -- cgit v1.2.3-70-g09d2