diff options
author | Kay Sievers <kay.sievers@suse.de> | 2006-09-05 02:18:06 +0200 |
---|---|---|
committer | Kay Sievers <kay.sievers@suse.de> | 2006-09-05 02:18:06 +0200 |
commit | eef5447934a07279bc76f3f65b0302ddea8556ab (patch) | |
tree | 83787f593db778e5471e03b441a5852e99618bca /udev_sysfs.c | |
parent | ac528431dd60c6b7f6b664ba430b937a11a32230 (diff) |
let $attr{symlink} return the last element of the path
Example for /block/sda:
SUBSYSTEMS="scsi", ENV{COMMENT}="$attr{driver}"
sets COMMENT=sd
SUBSYSTEMS="pci", ENV{COMMENT}="$attr{driver}"
sets COMMENT=ata_piix
Diffstat (limited to 'udev_sysfs.c')
-rw-r--r-- | udev_sysfs.c | 56 |
1 files changed, 40 insertions, 16 deletions
diff --git a/udev_sysfs.c b/udev_sysfs.c index c192696689..e733d417c5 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -346,6 +346,7 @@ char *sysfs_attr_get_value(const char *devpath, const char *attr_name) char value[NAME_SIZE]; struct sysfs_attr *attr_loop; struct sysfs_attr *attr; + struct stat statbuf; int fd; ssize_t size; size_t sysfs_len; @@ -375,25 +376,48 @@ char *sysfs_attr_get_value(const char *devpath, const char *attr_name) dbg("add to cache '%s'", path_full); list_add(&attr->node, &attr_list); - /* read attribute value */ - fd = open(path_full, O_RDONLY); - if (fd < 0) { - dbg("attribute '%s' does not exist", path_full); + if (lstat(path_full, &statbuf) != 0) { + dbg("stat '%s' failed: %s", path_full, strerror(errno)); goto out; } - size = read(fd, value, sizeof(value)); - close(fd); - if (size < 0) - goto out; - if (size == sizeof(value)) - goto out; - /* got a valid value, store and return it */ - value[size] = '\0'; - remove_trailing_chars(value, '\n'); - dbg("cache '%s' with value '%s'", path_full, value); - strlcpy(attr->value_local, value, sizeof(attr->value_local)); - attr->value = attr->value_local; + if (S_ISLNK(statbuf.st_mode)) { + /* links return the last element of the target path */ + char link_target[PATH_SIZE]; + int len; + const char *pos; + + len = readlink(path_full, link_target, sizeof(link_target)); + if (len > 0) { + link_target[len] = '\0'; + pos = strrchr(link_target, '/'); + if (pos != NULL) { + dbg("cache '%s' with link value '%s'", path_full, value); + strlcpy(attr->value_local, &pos[1], sizeof(attr->value_local)); + attr->value = attr->value_local; + } + } + } else { + /* read attribute value */ + fd = open(path_full, O_RDONLY); + if (fd < 0) { + dbg("attribute '%s' does not exist", path_full); + goto out; + } + size = read(fd, value, sizeof(value)); + close(fd); + if (size < 0) + goto out; + if (size == sizeof(value)) + goto out; + + /* got a valid value, store and return it */ + value[size] = '\0'; + remove_trailing_chars(value, '\n'); + dbg("cache '%s' with attribute value '%s'", path_full, value); + strlcpy(attr->value_local, value, sizeof(attr->value_local)); + attr->value = attr->value_local; + } out: return attr->value; |