From: Kay Sievers Date: Sun, 28 Sep 2008 20:18:40 +0000 (+0200) Subject: libudev: enumerate "subsystem" X-Git-Tag: 174~1521 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=6f67f1dfb7f5a8e59d479fe6af01eb267fd83e24 libudev: enumerate "subsystem" --- diff --git a/TODO b/TODO index 8d7858fbe..b1e6f9863 100644 --- a/TODO +++ b/TODO @@ -4,6 +4,7 @@ use enumerate for "trigger" o libudev queue - interface for /dev/.udev/queue/ state use queue interface for "settle" + o relace test/sys/ with current sysfs layout o use libudev device in udev_rules.c get rid of udevice, store rule matching state in rule iterator o rework rules to a match-action list, instead of a rules array diff --git a/udev/lib/libudev-enumerate.c b/udev/lib/libudev-enumerate.c index c7fb683c1..b71ded645 100644 --- a/udev/lib/libudev-enumerate.c +++ b/udev/lib/libudev-enumerate.c @@ -78,8 +78,10 @@ static int devices_scan_subsystem(struct udev *udev, util_strlcpy(path, udev_get_sys_path(udev), sizeof(path)); util_strlcat(path, basedir, sizeof(path)); - util_strlcat(path, "/", sizeof(path)); - util_strlcat(path, subsystem, sizeof(path)); + if (subsystem != NULL) { + util_strlcat(path, "/", sizeof(path)); + util_strlcat(path, subsystem, sizeof(path)); + } if (subdir != NULL) util_strlcat(path, subdir, sizeof(path)); dir = opendir(path); @@ -87,12 +89,17 @@ static int devices_scan_subsystem(struct udev *udev, return -1; for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { char syspath[UTIL_PATH_SIZE]; + struct stat statbuf; if (dent->d_name[0] == '.') continue; util_strlcpy(syspath, path, sizeof(syspath)); util_strlcat(syspath, "/", sizeof(syspath)); util_strlcat(syspath, dent->d_name, sizeof(syspath)); + if (stat(syspath, &statbuf) != 0) + continue; + if (!S_ISDIR(statbuf.st_mode)) + continue; util_resolve_sys_link(udev, syspath, sizeof(syspath)); list_entry_add(udev, devices_list, syspath, NULL, 1, 1); } @@ -156,6 +163,20 @@ static int devices_delay(struct udev *udev, const char *syspath) return 0; } +static struct udev_enumerate *enumerate_new(struct udev *udev) +{ + struct udev_enumerate *udev_enumerate; + + udev_enumerate = malloc(sizeof(struct udev_enumerate)); + if (udev_enumerate == NULL) + return NULL; + memset(udev_enumerate, 0x00, (sizeof(struct udev_enumerate))); + udev_enumerate->refcount = 1; + udev_enumerate->udev = udev; + list_init(&udev_enumerate->devices_list); + return udev_enumerate; +} + /** * udev_enumerate_new_from_devices: * @udev: udev library context @@ -177,13 +198,9 @@ struct udev_enumerate *udev_enumerate_new_from_devices(struct udev *udev, const if (udev == NULL) return NULL; - udev_enumerate = malloc(sizeof(struct udev_enumerate)); + udev_enumerate = enumerate_new(udev); if (udev_enumerate == NULL) return NULL; - memset(udev_enumerate, 0x00, (sizeof(struct udev_enumerate))); - udev_enumerate->refcount = 1; - udev_enumerate->udev = udev; - list_init(&udev_enumerate->devices_list); va_start(vargs, subsystem); list_init(&subsystem_include_list); @@ -200,18 +217,18 @@ struct udev_enumerate *udev_enumerate_new_from_devices(struct udev *udev, const util_strlcpy(base, udev_get_sys_path(udev), sizeof(base)); util_strlcat(base, "/subsystem", sizeof(base)); if (stat(base, &statbuf) == 0) { - info(udev, "searching 'subsystem/*/devices/*' dir\n"); + info(udev, "searching '/subsystem/*/devices/*' dir\n"); devices_scan_subsystems(udev, "/subsystem", "/devices", list_get_entry(&subsystem_include_list), list_get_entry(&subsystem_exclude_list), &udev_enumerate->devices_list); } else { - info(udev, "searching 'bus/*/devices/*' dir\n"); + info(udev, "searching '/bus/*/devices/*' dir\n"); devices_scan_subsystems(udev, "/bus", "/devices", list_get_entry(&subsystem_include_list), list_get_entry(&subsystem_exclude_list), &udev_enumerate->devices_list); - info(udev, "searching 'class/*' dir\n"); + info(udev, "searching '/class/*' dir\n"); devices_scan_subsystems(udev, "/class", NULL, list_get_entry(&subsystem_include_list), list_get_entry(&subsystem_exclude_list), @@ -231,5 +248,29 @@ struct udev_enumerate *udev_enumerate_new_from_devices(struct udev *udev, const struct udev_enumerate *udev_enumerate_new_from_subsystems(struct udev *udev) { - return NULL; + struct udev_enumerate *udev_enumerate; + char base[UTIL_PATH_SIZE]; + struct stat statbuf; + const char *subsysdir; + + if (udev == NULL) + return NULL; + + udev_enumerate = enumerate_new(udev); + if (udev_enumerate == NULL) + return NULL; + + util_strlcpy(base, udev_get_sys_path(udev), sizeof(base)); + util_strlcat(base, "/subsystem", sizeof(base)); + if (stat(base, &statbuf) == 0) + subsysdir = "/subsystem"; + else + subsysdir = "/bus"; + info(udev, "searching '%s/*' dir\n", subsysdir); + devices_scan_subsystem(udev, subsysdir, NULL, NULL, &udev_enumerate->devices_list); + info(udev, "searching '%s/*/drivers/*' dir\n", subsysdir); + devices_scan_subsystems(udev, subsysdir, "/drivers", + NULL, NULL, + &udev_enumerate->devices_list); + return udev_enumerate; } diff --git a/udev/lib/test-libudev.c b/udev/lib/test-libudev.c index 0f485248e..8ef7a6e3b 100644 --- a/udev/lib/test-libudev.c +++ b/udev/lib/test-libudev.c @@ -333,6 +333,13 @@ int main(int argc, char *argv[], char *envp[]) test_enumerate_print_list(enumerate); udev_enumerate_unref(enumerate); + printf("enumerate 'subsystem'\n"); + enumerate = udev_enumerate_new_from_subsystems(udev); + if (enumerate == NULL) + return -1; + test_enumerate_print_list(enumerate); + udev_enumerate_unref(enumerate); + test_monitor(udev, socket); out: udev_unref(udev);