From 2fdaa983a958822d79821c1afe51e22e7a3e00ff Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 17 Aug 2011 21:07:09 +0200 Subject: [PATCH] libudev: udev_device_get_sysattr_value() return syspath of custom links --- libudev/libudev-device.c | 43 ++++++++++++++++++++++------------------ udev/udevadm-info.c | 6 +++++- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/libudev/libudev-device.c b/libudev/libudev-device.c index 064ffad9bf3..991398c76d4 100644 --- a/libudev/libudev-device.c +++ b/libudev/libudev-device.c @@ -1373,27 +1373,32 @@ UDEV_EXPORT const char *udev_device_get_sysattr_value(struct udev_device *udev_d } if (S_ISLNK(statbuf.st_mode)) { - char target[UTIL_NAME_SIZE]; - int len; - char *pos; + struct udev_device *dev; - /* some core links return the last element of the target path */ - if (strcmp(sysattr, "driver") != 0 && - strcmp(sysattr, "subsystem") != 0 && - strcmp(sysattr, "module") != 0) - goto out; - - len = readlink(path, target, sizeof(target)); - if (len <= 0 || len == sizeof(target)) - goto out; - target[len] = '\0'; - - pos = strrchr(target, '/'); - if (pos != NULL) { - pos = &pos[1]; - dbg(udev_device->udev, "cache '%s' with link value '%s'\n", sysattr, pos); - list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, pos); + /* + * Some core links return only the last element of the target path, + * these are just values, the paths should not be exposed. + */ + if (strcmp(sysattr, "driver") == 0 || + strcmp(sysattr, "subsystem") == 0 || + strcmp(sysattr, "module") == 0) { + if (util_get_sys_core_link_value(udev_device->udev, sysattr, + udev_device->syspath, value, sizeof(value)) < 0) + return NULL; + dbg(udev_device->udev, "cache '%s' with link value '%s'\n", sysattr, value); + list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, value); val = udev_list_entry_get_value(list_entry); + goto out; + } + + /* resolve link to a device and return its syspath */ + util_strscpyl(path, sizeof(path), udev_device->syspath, "/", sysattr, NULL); + dev = udev_device_new_from_syspath(udev_device->udev, path); + if (dev != NULL) { + list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, + udev_device_get_syspath(dev)); + val = udev_list_entry_get_value(list_entry); + udev_device_unref(dev); } goto out; diff --git a/udev/udevadm-info.c b/udev/udevadm-info.c index 4053436fe64..f7e7e86b6a4 100644 --- a/udev/udevadm-info.c +++ b/udev/udevadm-info.c @@ -52,10 +52,10 @@ static bool skip_attribute(const char *name) static void print_all_attributes(struct udev_device *device, const char *key) { + struct udev *udev = udev_device_get_udev(device); struct udev_list_entry *sysattr; udev_list_entry_foreach(sysattr, udev_device_get_sysattr_list_entry(device)) { - struct udev *udev = udev_device_get_udev(device); const char *name; const char *value; size_t len; @@ -69,6 +69,10 @@ static void print_all_attributes(struct udev_device *device, const char *key) continue; dbg(udev, "attr '%s'='%s'\n", name, value); + /* skip any values that look like a path */ + if (value[0] == '/') + continue; + /* skip nonprintable attributes */ len = strlen(value); while (len > 0 && isprint(value[len-1]))