From 04a727df50fde3f69127aed4bc48e6cff5430175 Mon Sep 17 00:00:00 2001 From: illiliti Date: Tue, 18 Apr 2023 09:28:02 +0300 Subject: [PATCH] udev_device.c: consider device valid even if no subsystem symlink exists Some devices may not have subsystem symlinks, therefore we cannot rely on that to check if device is valid. Instead, check uevent file which should be always present in valid device. Reference: https://github.com/openwrt/openwrt/issues/12350 --- udev_device.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/udev_device.c b/udev_device.c index 173cbe4..7bf35d5 100644 --- a/udev_device.c +++ b/udev_device.c @@ -342,17 +342,17 @@ static char *read_symlink(const char *syspath, const char *name) return strdup(strrchr(link, '/') + 1); } -static void set_properties_from_uevent(struct udev_device *udev_device) +static int set_properties_from_uevent(struct udev_device *udev_device, const char *syspath) { - char line[LINE_MAX], path[PATH_MAX], devnode[PATH_MAX]; + char line[LINE_MAX], path[PATH_MAX + sizeof("/uevent")], devnode[PATH_MAX]; FILE *file; char *pos; - snprintf(path, sizeof(path), "%s/uevent", udev_device_get_syspath(udev_device)); + snprintf(path, sizeof(path), "%s/uevent", syspath); file = fopen(path, "r"); if (!file) { - return; + return -1; } while (fgets(line, sizeof(line), file)) { @@ -364,11 +364,12 @@ static void set_properties_from_uevent(struct udev_device *udev_device) } else if ((pos = strchr(line, '='))) { *pos = '\0'; - udev_list_entry_add(&udev_device->properties, line, pos + 1, 1); + udev_list_entry_add(&udev_device->properties, line, pos + 1, 0); } } fclose(file); + return 0; } static void make_bit(unsigned long *arr, int cnt, const char *str) @@ -543,21 +544,13 @@ struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char * return NULL; } - subsystem = read_symlink(syspath, "subsystem"); - - if (!subsystem) { - return NULL; - } - if (!realpath(syspath, path)) { - free(subsystem); return NULL; } udev_device = calloc(1, sizeof(*udev_device)); if (!udev_device) { - free(subsystem); return NULL; } @@ -568,11 +561,17 @@ struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char * udev_list_entry_init(&udev_device->properties); udev_list_entry_init(&udev_device->sysattrs); + if (set_properties_from_uevent(udev_device, path) == -1) { + free(udev_device); + return NULL; + } + udev_list_entry_add(&udev_device->properties, "SYSPATH", path, 0); udev_list_entry_add(&udev_device->properties, "DEVPATH", path + 4, 0); sysname = strrchr(path, '/') + 1; driver = read_symlink(path, "driver"); + subsystem = read_symlink(path, "subsystem"); udev_list_entry_add(&udev_device->properties, "SUBSYSTEM", subsystem, 0); udev_list_entry_add(&udev_device->properties, "SYSNAME", sysname, 0); @@ -585,7 +584,6 @@ struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char * } } - set_properties_from_uevent(udev_device); set_properties_from_evdev(udev_device); set_properties_from_props(udev_device);