chiark / gitweb /
libudev: add udev_device_new_from_devnum()
authorKay Sievers <kay.sievers@vrfy.org>
Mon, 22 Sep 2008 06:28:56 +0000 (23:28 -0700)
committerKay Sievers <kay.sievers@vrfy.org>
Mon, 22 Sep 2008 06:28:56 +0000 (23:28 -0700)
udev/lib/exported_symbols
udev/lib/libudev-device.c
udev/lib/libudev-util.c
udev/lib/libudev.h
udev/lib/test-libudev.c

index 5646bb59fa5a2b34d596f55e3bc2b8756144036c..8efd2914e2fba609b049049f2444ef8a8f7fd0d9 100644 (file)
@@ -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
index 731230efd0143858bd9da1072d60696fdbd6fd46..8103c7fcc46448c5812a5a393afa8217c9b83d7f 100644 (file)
@@ -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;
index 7eadc7f2961270842691b12b0b223dee5174a095..aa544fea2291da4be0c20642f70fee3c3e89c717 100644 (file)
@@ -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;
index 1970652f8fbfe0fa5d95e813e79d6eb1b180595e..4d5fd93efc0cc3430854b2bcc3d6f018ffe3aad8 100644 (file)
@@ -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);
index 0a0d754b38e34441453256efeb5f6e8d7271e730..8afd294a2fb33873ce4ae55dcfcf8eeb30be1992 100644 (file)
@@ -24,6 +24,7 @@
 #include <string.h>
 #include <getopt.h>
 #include <syslog.h>
+#include <fcntl.h>
 #include <sys/select.h>
 
 #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);