From 90d80c2efcf63c69c05e4788b993f688302b02a4 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 7 Oct 2008 20:20:34 +0200 Subject: [PATCH] libudev: device - add device lookup by subsystem:sysname --- udev/lib/exported_symbols | 1 + udev/lib/libudev-device.c | 88 ++++++++++++++++++++++++ udev/lib/libudev.h | 1 + udev/lib/test-libudev.c | 136 +++++++++++++++++++++++++------------- 4 files changed, 179 insertions(+), 47 deletions(-) diff --git a/udev/lib/exported_symbols b/udev/lib/exported_symbols index 2574d13e67..8e0be1ab8d 100644 --- a/udev/lib/exported_symbols +++ b/udev/lib/exported_symbols @@ -14,6 +14,7 @@ udev_list_entry_get_name udev_list_entry_get_value udev_device_new_from_syspath udev_device_new_from_devnum +udev_device_new_from_subsystem_sysname udev_device_get_parent udev_device_get_parent_with_subsystem udev_device_ref diff --git a/udev/lib/libudev-device.c b/udev/lib/libudev-device.c index 55fcad655e..0cb992c9ea 100644 --- a/udev/lib/libudev-device.c +++ b/udev/lib/libudev-device.c @@ -381,6 +381,94 @@ struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, de return device; } +struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname) +{ + size_t sys_path_len; + char path_full[UTIL_PATH_SIZE]; + char *path; + struct stat statbuf; + + sys_path_len = util_strlcpy(path_full, udev_get_sys_path(udev), sizeof(path_full)); + path = &path_full[sys_path_len]; + + if (strcmp(subsystem, "subsystem") == 0) { + util_strlcpy(path, "/subsystem/", sizeof(path_full) - sys_path_len); + util_strlcat(path, sysname, sizeof(path_full) - sys_path_len); + if (stat(path_full, &statbuf) == 0) + goto found; + + util_strlcpy(path, "/bus/", sizeof(path_full) - sys_path_len); + util_strlcat(path, sysname, sizeof(path_full) - sys_path_len); + if (stat(path_full, &statbuf) == 0) + goto found; + + util_strlcpy(path, "/class/", sizeof(path_full) - sys_path_len); + util_strlcat(path, sysname, sizeof(path_full) - sys_path_len); + if (stat(path_full, &statbuf) == 0) + goto found; + goto out; + } + + if (strcmp(subsystem, "module") == 0) { + util_strlcpy(path, "/module/", sizeof(path_full) - sys_path_len); + util_strlcat(path, sysname, sizeof(path_full) - sys_path_len); + if (stat(path_full, &statbuf) == 0) + goto found; + goto out; + } + + if (strcmp(subsystem, "drivers") == 0) { + char subsys[UTIL_NAME_SIZE]; + char *driver; + + util_strlcpy(subsys, sysname, sizeof(subsys)); + driver = strchr(subsys, ':'); + if (driver != NULL) { + driver[0] = '\0'; + driver = &driver[1]; + util_strlcpy(path, "/subsystem/", sizeof(path_full) - sys_path_len); + util_strlcat(path, subsys, sizeof(path_full) - sys_path_len); + util_strlcat(path, "/drivers/", sizeof(path_full) - sys_path_len); + util_strlcat(path, driver, sizeof(path_full) - sys_path_len); + if (stat(path_full, &statbuf) == 0) + goto found; + + util_strlcpy(path, "/bus/", sizeof(path_full) - sys_path_len); + util_strlcat(path, subsys, sizeof(path_full) - sys_path_len); + util_strlcat(path, "/drivers/", sizeof(path_full) - sys_path_len); + util_strlcat(path, driver, sizeof(path_full) - sys_path_len); + if (stat(path_full, &statbuf) == 0) + goto found; + } + goto out; + } + + util_strlcpy(path, "/subsystem/", sizeof(path_full) - sys_path_len); + util_strlcat(path, subsystem, sizeof(path_full) - sys_path_len); + util_strlcat(path, "/devices/", sizeof(path_full) - sys_path_len); + util_strlcat(path, sysname, sizeof(path_full) - sys_path_len); + if (stat(path_full, &statbuf) == 0) + goto found; + + util_strlcpy(path, "/bus/", sizeof(path_full) - sys_path_len); + util_strlcat(path, subsystem, sizeof(path_full) - sys_path_len); + util_strlcat(path, "/devices/", sizeof(path_full) - sys_path_len); + util_strlcat(path, sysname, sizeof(path_full) - sys_path_len); + if (stat(path_full, &statbuf) == 0) + goto found; + + util_strlcpy(path, "/class/", sizeof(path_full) - sys_path_len); + util_strlcat(path, subsystem, sizeof(path_full) - sys_path_len); + util_strlcat(path, "/", sizeof(path_full) - sys_path_len); + util_strlcat(path, sysname, sizeof(path_full) - sys_path_len); + if (stat(path_full, &statbuf) == 0) + goto found; +out: + return NULL; +found: + return udev_device_new_from_syspath(udev, path_full); +} + static struct udev_device *device_new_from_parent(struct udev_device *udev_device) { struct udev_device *udev_device_parent = NULL; diff --git a/udev/lib/libudev.h b/udev/lib/libudev.h index fabe59d7d7..3f4cccf8c3 100644 --- a/udev/lib/libudev.h +++ b/udev/lib/libudev.h @@ -59,6 +59,7 @@ extern const char *udev_list_entry_get_value(struct udev_list_entry *list_entry) struct udev_device; extern struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char *syspath); extern struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum); +extern struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname); extern struct udev_device *udev_device_get_parent(struct udev_device *udev_device); extern struct udev_device *udev_device_get_parent_with_subsystem(struct udev_device *udev_device, const char *subsystem); extern struct udev_device *udev_device_ref(struct udev_device *udev_device); diff --git a/udev/lib/test-libudev.c b/udev/lib/test-libudev.c index 854a0a9faa..65d84159ce 100644 --- a/udev/lib/test-libudev.c +++ b/udev/lib/test-libudev.c @@ -154,6 +154,40 @@ static int test_device_devnum(struct udev *udev) return 0; } +static int test_device_subsys_name(struct udev *udev) +{ + struct udev_device *device; + + printf("looking up device: 'block':'sda'\n"); + device = udev_device_new_from_subsystem_sysname(udev, "block", "sda"); + if (device == NULL) + return -1; + print_device(device); + udev_device_unref(device); + + printf("looking up device: 'subsystem':'pci'\n"); + device = udev_device_new_from_subsystem_sysname(udev, "subsystem", "pci"); + if (device == NULL) + return -1; + print_device(device); + udev_device_unref(device); + + printf("looking up device: 'drivers':'scsi:sd'\n"); + device = udev_device_new_from_subsystem_sysname(udev, "drivers", "scsi:sd"); + if (device == NULL) + return -1; + print_device(device); + udev_device_unref(device); + + printf("looking up device: 'module':'printk'\n"); + device = udev_device_new_from_subsystem_sysname(udev, "module", "printk"); + if (device == NULL) + return -1; + print_device(device); + udev_device_unref(device); + return 0; +} + static int test_enumerate_print_list(struct udev_enumerate *enumerate) { struct udev_list_entry *list_entry; @@ -269,7 +303,59 @@ static int test_queue(struct udev *udev) return 0; } -int main(int argc, char *argv[], char *envp[]) +static int test_enumerate(struct udev *udev, const char *subsystem) +{ + struct udev_enumerate *udev_enumerate; + + printf("enumerate '%s'\n", subsystem == NULL ? "" : subsystem); + udev_enumerate = udev_enumerate_new(udev); + if (udev_enumerate == NULL) + return -1; + udev_enumerate_add_match_subsystem(udev_enumerate, subsystem); + udev_enumerate_scan_devices(udev_enumerate); + test_enumerate_print_list(udev_enumerate); + udev_enumerate_unref(udev_enumerate); + + printf("enumerate 'block'\n"); + udev_enumerate = udev_enumerate_new(udev); + if (udev_enumerate == NULL) + return -1; + udev_enumerate_add_match_subsystem(udev_enumerate,"block"); + udev_enumerate_scan_devices(udev_enumerate); + test_enumerate_print_list(udev_enumerate); + udev_enumerate_unref(udev_enumerate); + + printf("enumerate 'not block'\n"); + udev_enumerate = udev_enumerate_new(udev); + if (udev_enumerate == NULL) + return -1; + udev_enumerate_add_nomatch_subsystem(udev_enumerate, "block"); + udev_enumerate_scan_devices(udev_enumerate); + test_enumerate_print_list(udev_enumerate); + udev_enumerate_unref(udev_enumerate); + + printf("enumerate 'pci, mem, vc'\n"); + udev_enumerate = udev_enumerate_new(udev); + if (udev_enumerate == NULL) + return -1; + udev_enumerate_add_match_subsystem(udev_enumerate, "pci"); + udev_enumerate_add_match_subsystem(udev_enumerate, "mem"); + udev_enumerate_add_match_subsystem(udev_enumerate, "vc"); + udev_enumerate_scan_devices(udev_enumerate); + test_enumerate_print_list(udev_enumerate); + udev_enumerate_unref(udev_enumerate); + + printf("enumerate 'subsystem'\n"); + udev_enumerate = udev_enumerate_new(udev); + if (udev_enumerate == NULL) + return -1; + udev_enumerate_scan_subsystems(udev_enumerate); + test_enumerate_print_list(udev_enumerate); + udev_enumerate_unref(udev_enumerate); + return 0; +} + +int main(int argc, char *argv[]) { struct udev *udev = NULL; static const struct option options[] = { @@ -281,7 +367,6 @@ int main(int argc, char *argv[], char *envp[]) { "version", no_argument, NULL, 'V' }, {} }; - struct udev_enumerate *udev_enumerate; const char *syspath = "/devices/virtual/mem/null"; const char *subsystem = NULL; const char *socket = "@/org/kernel/udev/monitor"; @@ -342,53 +427,10 @@ int main(int argc, char *argv[], char *envp[]) test_device(udev, syspath); test_device_devnum(udev); + test_device_subsys_name(udev); test_device_parents(udev, syspath); - printf("enumerate '%s'\n", subsystem == NULL ? "" : subsystem); - udev_enumerate = udev_enumerate_new(udev); - if (udev_enumerate == NULL) - return -1; - udev_enumerate_add_match_subsystem(udev_enumerate, subsystem); - udev_enumerate_scan_devices(udev_enumerate); - test_enumerate_print_list(udev_enumerate); - udev_enumerate_unref(udev_enumerate); - - printf("enumerate 'block'\n"); - udev_enumerate = udev_enumerate_new(udev); - if (udev_enumerate == NULL) - return -1; - udev_enumerate_add_match_subsystem(udev_enumerate,"block"); - udev_enumerate_scan_devices(udev_enumerate); - test_enumerate_print_list(udev_enumerate); - udev_enumerate_unref(udev_enumerate); - - printf("enumerate 'not block'\n"); - udev_enumerate = udev_enumerate_new(udev); - if (udev_enumerate == NULL) - return -1; - udev_enumerate_add_nomatch_subsystem(udev_enumerate, "block"); - udev_enumerate_scan_devices(udev_enumerate); - test_enumerate_print_list(udev_enumerate); - udev_enumerate_unref(udev_enumerate); - - printf("enumerate 'pci, mem, vc'\n"); - udev_enumerate = udev_enumerate_new(udev); - if (udev_enumerate == NULL) - return -1; - udev_enumerate_add_match_subsystem(udev_enumerate, "pci"); - udev_enumerate_add_match_subsystem(udev_enumerate, "mem"); - udev_enumerate_add_match_subsystem(udev_enumerate, "vc"); - udev_enumerate_scan_devices(udev_enumerate); - test_enumerate_print_list(udev_enumerate); - udev_enumerate_unref(udev_enumerate); - - printf("enumerate 'subsystem'\n"); - udev_enumerate = udev_enumerate_new(udev); - if (udev_enumerate == NULL) - return -1; - udev_enumerate_scan_subsystems(udev_enumerate); - test_enumerate_print_list(udev_enumerate); - udev_enumerate_unref(udev_enumerate); + test_enumerate(udev, subsystem); test_queue(udev);