From 4c9dff47f696b1e6c89cc6e0a7ba683067927821 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 21 Sep 2008 23:28:56 -0700 Subject: [PATCH] libudev: add udev_device_new_from_devnum() --- udev/lib/exported_symbols | 1 + udev/lib/libudev-device.c | 14 ++++++++++++++ udev/lib/libudev-util.c | 5 +++++ udev/lib/libudev.h | 1 + udev/lib/test-libudev.c | 16 ++++++++++++++++ 5 files changed, 37 insertions(+) diff --git a/udev/lib/exported_symbols b/udev/lib/exported_symbols index 5646bb59f..8efd2914e 100644 --- a/udev/lib/exported_symbols +++ b/udev/lib/exported_symbols @@ -8,6 +8,7 @@ udev_set_log_priority udev_get_sys_path udev_get_dev_path udev_device_new_from_syspath +udev_device_new_from_devnum udev_device_get_parent udev_device_ref udev_device_unref diff --git a/udev/lib/libudev-device.c b/udev/lib/libudev-device.c index 731230efd..8103c7fcc 100644 --- a/udev/lib/libudev-device.c +++ b/udev/lib/libudev-device.c @@ -216,6 +216,20 @@ struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char * return udev_device; } +struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum) +{ + char path[UTIL_PATH_SIZE]; + + snprintf(path, sizeof(path), "%s/dev/%s/%u:%u", + udev_get_sys_path(udev), + type == 'b' ? "block" : "char", + major(devnum), minor(devnum)); + if (util_resolve_sys_link(udev, path, sizeof(path)) < 0) + return NULL; + + return udev_device_new_from_syspath(udev, path); +} + 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-util.c b/udev/lib/libudev-util.c index 7eadc7f29..aa544fea2 100644 --- a/udev/lib/libudev-util.c +++ b/udev/lib/libudev-util.c @@ -64,12 +64,17 @@ ssize_t util_get_sys_driver(struct udev *udev, const char *syspath, char *driver int util_resolve_sys_link(struct udev *udev, char *syspath, size_t size) { + struct stat statbuf; char link_target[UTIL_PATH_SIZE]; int len; int i; int back; + if (lstat(syspath, &statbuf) < 0) + return -1; + if (!S_ISLNK(statbuf.st_mode)) + return -1; len = readlink(syspath, link_target, sizeof(link_target)); if (len <= 0) return -1; diff --git a/udev/lib/libudev.h b/udev/lib/libudev.h index 1970652f8..4d5fd93ef 100644 --- a/udev/lib/libudev.h +++ b/udev/lib/libudev.h @@ -46,6 +46,7 @@ extern void udev_selinux_lsetfilecon(struct udev *udev, const char *file, unsign 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_get_parent(struct udev_device *udev_device); extern struct udev_device *udev_device_ref(struct udev_device *udev_device); extern void udev_device_unref(struct udev_device *udev_device); diff --git a/udev/lib/test-libudev.c b/udev/lib/test-libudev.c index 0a0d754b3..8afd294a2 100644 --- a/udev/lib/test-libudev.c +++ b/udev/lib/test-libudev.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "libudev.h" @@ -114,6 +115,20 @@ static int test_device_parents(struct udev *udev, const char *syspath) return 0; } +static int test_device_devnum(struct udev *udev) +{ + dev_t devnum = makedev(1, 3); + struct udev_device *device; + + printf("looking up device: %u:%u\n", major(devnum), minor(devnum)); + device = udev_device_new_from_devnum(udev, 'c', devnum); + if (device == NULL) + return -1; + print_device(device); + udev_device_unref(device); + return 0; +} + static int devices_enum_cb(struct udev_device *device, void *data) { printf("device: '%s' (%s) '%s'\n", @@ -253,6 +268,7 @@ int main(int argc, char *argv[], char *envp[]) } test_device(udev, syspath); + test_device_devnum(udev); test_device_parents(udev, syspath); test_enumerate(udev, subsystem); test_monitor(udev, socket); -- 2.30.2