+struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum)
+{
+ char path[UTIL_PATH_SIZE];
+ const char *type_str;
+ struct udev_enumerate *udev_enumerate;
+ struct udev_list_entry *list_entry;
+ struct udev_device *device = NULL;
+
+ if (type == 'b')
+ type_str = "block";
+ else if (type == 'c')
+ type_str = "char";
+ else
+ return NULL;
+
+ /* /sys/dev/{block,char}/<maj>:<min> link */
+ snprintf(path, sizeof(path), "%s/dev/%s/%u:%u", udev_get_sys_path(udev),
+ type_str, major(devnum), minor(devnum));
+ if (util_resolve_sys_link(udev, path, sizeof(path)) == 0)
+ return udev_device_new_from_syspath(udev, path);
+
+ udev_enumerate = udev_enumerate_new(udev);
+ if (udev_enumerate == NULL)
+ return NULL;
+
+ /* fallback to search sys devices for the major/minor */
+ if (type == 'b')
+ udev_enumerate_scan_devices(udev_enumerate, "block", NULL);
+ else if (type == 'c')
+ udev_enumerate_scan_devices(udev_enumerate, "!block", NULL);
+ udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(udev_enumerate)) {
+ struct udev_device *device_loop;
+
+ device_loop = udev_device_new_from_syspath(udev, udev_list_entry_get_name(list_entry));
+ if (device_loop != NULL) {
+ if (udev_device_get_devnum(device_loop) == devnum) {
+ const char *subsystem;
+
+ subsystem = udev_device_get_subsystem(device_loop);
+ if (type == 'b' && strcmp(subsystem, "block") != 0)
+ continue;
+ if (type == 'c' && strcmp(subsystem, "block") == 0)
+ continue;
+ device = device_loop;
+ break;
+ }
+ udev_device_unref(device_loop);
+ }
+ }
+ udev_enumerate_unref(udev_enumerate);
+ return device;
+}
+