summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@vrfy.org>2008-10-15 18:34:14 +0200
committerKay Sievers <kay.sievers@vrfy.org>2008-10-15 18:34:14 +0200
commit5c5cad796682d7f481d59ca495a1efa07fa013c7 (patch)
tree5af82e9b1171294f04285d0c654ae049d68c9000
parentbd85566c16bd9ba32a44a1b2902127f459f4a63c (diff)
libudev: device - lookup "subsystem" and "driver" only once
-rw-r--r--udev/lib/libudev-device.c64
-rw-r--r--udev/lib/libudev-util.c4
2 files changed, 36 insertions, 32 deletions
diff --git a/udev/lib/libudev-device.c b/udev/lib/libudev-device.c
index 5b90af68b8..8afd68cc76 100644
--- a/udev/lib/libudev-device.c
+++ b/udev/lib/libudev-device.c
@@ -41,12 +41,14 @@ struct udev_device {
const char *sysnum;
char *devnode;
char *subsystem;
+ int subsystem_set;
struct udev_list_node devlinks_list;
int devlinks_uptodate;
struct udev_list_node properties_list;
char *envp[128];
int envp_uptodate;
char *driver;
+ int driver_set;
dev_t devnum;
char *action;
int event_timeout;
@@ -687,31 +689,30 @@ const char *udev_device_get_subsystem(struct udev_device *udev_device)
if (udev_device == NULL)
return NULL;
- if (udev_device->subsystem != NULL)
- return udev_device->subsystem;
-
- /* read "subsytem" link */
- if (util_get_sys_subsystem(udev_device->udev, udev_device->syspath, subsystem, sizeof(subsystem)) > 0) {
- udev_device->subsystem = strdup(subsystem);
- return udev_device->subsystem;
- }
-
- /* implicit names */
- if (strncmp(udev_device->devpath, "/module/", 8) == 0) {
- udev_device->subsystem = strdup("module");
- return udev_device->subsystem;
- }
- if (strstr(udev_device->devpath, "/drivers/") != NULL) {
- udev_device->subsystem = strdup("drivers");
- return udev_device->subsystem;
- }
- if (strncmp(udev_device->devpath, "/subsystem/", 11) == 0 ||
- strncmp(udev_device->devpath, "/class/", 7) == 0 ||
- strncmp(udev_device->devpath, "/bus/", 5) == 0) {
- udev_device->subsystem = strdup("subsystem");
- return udev_device->subsystem;
+ if (!udev_device->subsystem_set) {
+ udev_device->subsystem_set = 1;
+ /* read "subsytem" link */
+ if (util_get_sys_subsystem(udev_device->udev, udev_device->syspath, subsystem, sizeof(subsystem)) > 0) {
+ udev_device_set_subsystem(udev_device, subsystem);
+ return udev_device->subsystem;
+ }
+ /* implicit names */
+ if (strncmp(udev_device->devpath, "/module/", 8) == 0) {
+ udev_device_set_subsystem(udev_device, "module");
+ return udev_device->subsystem;
+ }
+ if (strstr(udev_device->devpath, "/drivers/") != NULL) {
+ udev_device_set_subsystem(udev_device, "drivers");
+ return udev_device->subsystem;
+ }
+ if (strncmp(udev_device->devpath, "/subsystem/", 11) == 0 ||
+ strncmp(udev_device->devpath, "/class/", 7) == 0 ||
+ strncmp(udev_device->devpath, "/bus/", 5) == 0) {
+ udev_device_set_subsystem(udev_device, "subsystem");
+ return udev_device->subsystem;
+ }
}
- return NULL;
+ return udev_device->subsystem;
}
/**
@@ -784,11 +785,11 @@ const char *udev_device_get_driver(struct udev_device *udev_device)
if (udev_device == NULL)
return NULL;
- if (udev_device->driver != NULL)
- return udev_device->driver;
- if (util_get_sys_driver(udev_device->udev, udev_device->syspath, driver, sizeof(driver)) < 2)
- return NULL;
- udev_device->driver = strdup(driver);
+ if (!udev_device->driver_set) {
+ udev_device->driver_set = 1;
+ if (util_get_sys_driver(udev_device->udev, udev_device->syspath, driver, sizeof(driver)) > 0)
+ udev_device->driver = strdup(driver);
+ }
return udev_device->driver;
}
@@ -844,7 +845,8 @@ const char *udev_device_get_attr_value(struct udev_device *udev_device, const ch
util_strlcat(path, attr, sizeof(path));
if (lstat(path, &statbuf) != 0) {
- info(udev_device->udev, "stat '%s' failed: %m\n", path);
+ info(udev_device->udev, "no attribute '%s', keep negative entry\n", path);
+ udev_list_entry_add(udev_device->udev, &udev_device->attr_list, attr, NULL, 0, 0);
goto out;
}
@@ -938,6 +940,7 @@ int udev_device_set_subsystem(struct udev_device *udev_device, const char *subsy
udev_device->subsystem = strdup(subsystem);
if (udev_device->subsystem == NULL)
return -ENOMEM;
+ udev_device->subsystem_set = 1;
udev_device_add_property(udev_device, "SUBSYSTEM", udev_device->subsystem);
return 0;
}
@@ -1023,6 +1026,7 @@ int udev_device_set_driver(struct udev_device *udev_device, const char *driver)
udev_device->driver = strdup(driver);
if (udev_device->driver == NULL)
return -ENOMEM;
+ udev_device->driver_set = 1;
return 0;
}
diff --git a/udev/lib/libudev-util.c b/udev/lib/libudev-util.c
index 55bac9a476..0ff121d774 100644
--- a/udev/lib/libudev-util.c
+++ b/udev/lib/libudev-util.c
@@ -31,7 +31,7 @@
#include "libudev.h"
#include "libudev-private.h"
-static ssize_t get_sys_link(struct udev *udev, const char *slink, const char *syspath, char *subsystem, size_t size)
+static ssize_t get_sys_link(struct udev *udev, const char *slink, const char *syspath, char *value, size_t size)
{
char path[UTIL_PATH_SIZE];
ssize_t len;
@@ -49,7 +49,7 @@ static ssize_t get_sys_link(struct udev *udev, const char *slink, const char *sy
return -1;
pos = &pos[1];
info(udev, "resolved link to: '%s'\n", pos);
- return util_strlcpy(subsystem, pos, size);
+ return util_strlcpy(value, pos, size);
}
ssize_t util_get_sys_subsystem(struct udev *udev, const char *syspath, char *subsystem, size_t size)