2 * libudev - interface to udev device information
4 * Copyright (C) 2008-2010 Kay Sievers <kay.sievers@vrfy.org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
22 #include <sys/param.h>
25 #include "libudev-private.h"
28 * SECTION:libudev-enumerate
29 * @short_description: lookup and sort sys devices
31 * Lookup devices in the sys filesystem, filter devices by properties,
32 * and return a sorted list of devices.
43 * Opaque object representing one device lookup/sort context.
45 struct udev_enumerate {
48 struct udev_list sysattr_match_list;
49 struct udev_list sysattr_nomatch_list;
50 struct udev_list subsystem_match_list;
51 struct udev_list subsystem_nomatch_list;
52 struct udev_list sysname_match_list;
53 struct udev_list properties_match_list;
54 struct udev_list tags_match_list;
55 struct udev_device *parent_match;
56 struct udev_list devices_list;
57 struct syspath *devices;
58 unsigned int devices_cur;
59 unsigned int devices_max;
60 bool devices_uptodate:1;
61 bool match_is_initialized;
66 * @udev: udev library context
68 * Create an enumeration context to scan /sys.
70 * Returns: an enumeration context.
72 _public_ struct udev_enumerate *udev_enumerate_new(struct udev *udev)
74 struct udev_enumerate *udev_enumerate;
76 udev_enumerate = calloc(1, sizeof(struct udev_enumerate));
77 if (udev_enumerate == NULL)
79 udev_enumerate->refcount = 1;
80 udev_enumerate->udev = udev;
81 udev_list_init(udev, &udev_enumerate->sysattr_match_list, false);
82 udev_list_init(udev, &udev_enumerate->sysattr_nomatch_list, false);
83 udev_list_init(udev, &udev_enumerate->subsystem_match_list, true);
84 udev_list_init(udev, &udev_enumerate->subsystem_nomatch_list, true);
85 udev_list_init(udev, &udev_enumerate->sysname_match_list, true);
86 udev_list_init(udev, &udev_enumerate->properties_match_list, false);
87 udev_list_init(udev, &udev_enumerate->tags_match_list, true);
88 udev_list_init(udev, &udev_enumerate->devices_list, false);
89 return udev_enumerate;
94 * @udev_enumerate: context
96 * Take a reference of a enumeration context.
98 * Returns: the passed enumeration context
100 _public_ struct udev_enumerate *udev_enumerate_ref(struct udev_enumerate *udev_enumerate)
102 if (udev_enumerate == NULL)
104 udev_enumerate->refcount++;
105 return udev_enumerate;
109 * udev_enumerate_unref:
110 * @udev_enumerate: context
112 * Drop a reference of an enumeration context. If the refcount reaches zero,
113 * all resources of the enumeration context will be released.
115 _public_ void udev_enumerate_unref(struct udev_enumerate *udev_enumerate)
119 if (udev_enumerate == NULL)
121 udev_enumerate->refcount--;
122 if (udev_enumerate->refcount > 0)
124 udev_list_cleanup(&udev_enumerate->sysattr_match_list);
125 udev_list_cleanup(&udev_enumerate->sysattr_nomatch_list);
126 udev_list_cleanup(&udev_enumerate->subsystem_match_list);
127 udev_list_cleanup(&udev_enumerate->subsystem_nomatch_list);
128 udev_list_cleanup(&udev_enumerate->sysname_match_list);
129 udev_list_cleanup(&udev_enumerate->properties_match_list);
130 udev_list_cleanup(&udev_enumerate->tags_match_list);
131 udev_device_unref(udev_enumerate->parent_match);
132 udev_list_cleanup(&udev_enumerate->devices_list);
133 for (i = 0; i < udev_enumerate->devices_cur; i++)
134 free(udev_enumerate->devices[i].syspath);
135 free(udev_enumerate->devices);
136 free(udev_enumerate);
140 * udev_enumerate_get_udev:
141 * @udev_enumerate: context
143 * Get the udev library context.
145 * Returns: a pointer to the context.
147 _public_ struct udev *udev_enumerate_get_udev(struct udev_enumerate *udev_enumerate)
149 if (udev_enumerate == NULL)
151 return udev_enumerate->udev;
154 static int syspath_add(struct udev_enumerate *udev_enumerate, const char *syspath)
157 struct syspath *entry;
159 /* double array size if needed */
160 if (udev_enumerate->devices_cur >= udev_enumerate->devices_max) {
164 add = udev_enumerate->devices_max;
167 buf = realloc(udev_enumerate->devices, (udev_enumerate->devices_max + add) * sizeof(struct syspath));
170 udev_enumerate->devices = buf;
171 udev_enumerate->devices_max += add;
174 path = strdup(syspath);
177 entry = &udev_enumerate->devices[udev_enumerate->devices_cur];
178 entry->syspath = path;
179 entry->len = strlen(path);
180 udev_enumerate->devices_cur++;
181 udev_enumerate->devices_uptodate = false;
185 static int syspath_cmp(const void *p1, const void *p2)
187 const struct syspath *path1 = p1;
188 const struct syspath *path2 = p2;
192 len = MIN(path1->len, path2->len);
193 ret = memcmp(path1->syspath, path2->syspath, len);
195 if (path1->len < path2->len)
197 else if (path1->len > path2->len)
203 /* For devices that should be moved to the absolute end of the list */
204 static bool devices_delay_end(struct udev *udev, const char *syspath)
206 static const char *delay_device_list[] = {
213 for (i = 0; delay_device_list[i] != NULL; i++) {
214 if (strstr(syspath + strlen("/sys"), delay_device_list[i]) != NULL)
220 /* For devices that should just be moved a little bit later, just
221 * before the point where some common path prefix changes. Returns the
222 * number of characters that make up that common prefix */
223 static size_t devices_delay_later(struct udev *udev, const char *syspath)
227 /* For sound cards the control device must be enumerated last
228 * to make sure it's the final device node that gets ACLs
229 * applied. Applications rely on this fact and use ACL changes
230 * on the control node as an indicator that the ACL change of
231 * the entire sound card completed. The kernel makes this
232 * guarantee when creating those devices, and hence we should
233 * too when enumerating them. */
235 if ((c = strstr(syspath, "/sound/card"))) {
237 c += strcspn(c, "/");
239 if (startswith(c, "/controlC"))
240 return c - syspath + 1;
247 * udev_enumerate_get_list_entry:
248 * @udev_enumerate: context
250 * Get the first entry of the sorted list of device paths.
252 * Returns: a udev_list_entry.
254 _public_ struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enumerate *udev_enumerate)
256 if (udev_enumerate == NULL)
258 if (!udev_enumerate->devices_uptodate) {
261 struct syspath *prev = NULL, *move_later = NULL;
262 size_t move_later_prefix = 0;
264 udev_list_cleanup(&udev_enumerate->devices_list);
265 qsort(udev_enumerate->devices, udev_enumerate->devices_cur, sizeof(struct syspath), syspath_cmp);
267 max = udev_enumerate->devices_cur;
268 for (i = 0; i < max; i++) {
269 struct syspath *entry = &udev_enumerate->devices[i];
271 /* skip duplicated entries */
273 entry->len == prev->len &&
274 memcmp(entry->syspath, prev->syspath, entry->len) == 0)
278 /* skip to be delayed devices, and add them to the end of the list */
279 if (devices_delay_end(udev_enumerate->udev, entry->syspath)) {
280 syspath_add(udev_enumerate, entry->syspath);
281 /* need to update prev here for the case realloc() gives a different address */
282 prev = &udev_enumerate->devices[i];
286 /* skip to be delayed devices, and move the to
287 * the point where the prefix changes. We can
288 * only move one item at a time. */
290 move_later_prefix = devices_delay_later(udev_enumerate->udev, entry->syspath);
292 if (move_later_prefix > 0) {
299 strncmp(entry->syspath, move_later->syspath, move_later_prefix) != 0) {
301 udev_list_entry_add(&udev_enumerate->devices_list, move_later->syspath, NULL);
305 udev_list_entry_add(&udev_enumerate->devices_list, entry->syspath, NULL);
309 udev_list_entry_add(&udev_enumerate->devices_list, move_later->syspath, NULL);
311 /* add and cleanup delayed devices from end of list */
312 for (i = max; i < udev_enumerate->devices_cur; i++) {
313 struct syspath *entry = &udev_enumerate->devices[i];
315 udev_list_entry_add(&udev_enumerate->devices_list, entry->syspath, NULL);
316 free(entry->syspath);
318 udev_enumerate->devices_cur = max;
320 udev_enumerate->devices_uptodate = true;
322 return udev_list_get_entry(&udev_enumerate->devices_list);
326 * udev_enumerate_add_match_subsystem:
327 * @udev_enumerate: context
328 * @subsystem: filter for a subsystem of the device to include in the list
330 * Match only devices belonging to a certain kernel subsystem.
332 * Returns: 0 on success, otherwise a negative error value.
334 _public_ int udev_enumerate_add_match_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem)
336 if (udev_enumerate == NULL)
338 if (subsystem == NULL)
340 if (udev_list_entry_add(&udev_enumerate->subsystem_match_list, subsystem, NULL) == NULL)
346 * udev_enumerate_add_nomatch_subsystem:
347 * @udev_enumerate: context
348 * @subsystem: filter for a subsystem of the device to exclude from the list
350 * Match only devices not belonging to a certain kernel subsystem.
352 * Returns: 0 on success, otherwise a negative error value.
354 _public_ int udev_enumerate_add_nomatch_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem)
356 if (udev_enumerate == NULL)
358 if (subsystem == NULL)
360 if (udev_list_entry_add(&udev_enumerate->subsystem_nomatch_list, subsystem, NULL) == NULL)
366 * udev_enumerate_add_match_sysattr:
367 * @udev_enumerate: context
368 * @sysattr: filter for a sys attribute at the device to include in the list
369 * @value: optional value of the sys attribute
371 * Match only devices with a certain /sys device attribute.
373 * Returns: 0 on success, otherwise a negative error value.
375 _public_ int udev_enumerate_add_match_sysattr(struct udev_enumerate *udev_enumerate, const char *sysattr, const char *value)
377 if (udev_enumerate == NULL)
381 if (udev_list_entry_add(&udev_enumerate->sysattr_match_list, sysattr, value) == NULL)
387 * udev_enumerate_add_nomatch_sysattr:
388 * @udev_enumerate: context
389 * @sysattr: filter for a sys attribute at the device to exclude from the list
390 * @value: optional value of the sys attribute
392 * Match only devices not having a certain /sys device attribute.
394 * Returns: 0 on success, otherwise a negative error value.
396 _public_ int udev_enumerate_add_nomatch_sysattr(struct udev_enumerate *udev_enumerate, const char *sysattr, const char *value)
398 if (udev_enumerate == NULL)
402 if (udev_list_entry_add(&udev_enumerate->sysattr_nomatch_list, sysattr, value) == NULL)
407 static int match_sysattr_value(struct udev_device *dev, const char *sysattr, const char *match_val)
409 const char *val = NULL;
412 val = udev_device_get_sysattr_value(dev, sysattr);
415 if (match_val == NULL) {
419 if (fnmatch(match_val, val, 0) == 0) {
428 * udev_enumerate_add_match_property:
429 * @udev_enumerate: context
430 * @property: filter for a property of the device to include in the list
431 * @value: value of the property
433 * Match only devices with a certain property.
435 * Returns: 0 on success, otherwise a negative error value.
437 _public_ int udev_enumerate_add_match_property(struct udev_enumerate *udev_enumerate, const char *property, const char *value)
439 if (udev_enumerate == NULL)
441 if (property == NULL)
443 if (udev_list_entry_add(&udev_enumerate->properties_match_list, property, value) == NULL)
449 * udev_enumerate_add_match_tag:
450 * @udev_enumerate: context
451 * @tag: filter for a tag of the device to include in the list
453 * Match only devices with a certain tag.
455 * Returns: 0 on success, otherwise a negative error value.
457 _public_ int udev_enumerate_add_match_tag(struct udev_enumerate *udev_enumerate, const char *tag)
459 if (udev_enumerate == NULL)
463 if (udev_list_entry_add(&udev_enumerate->tags_match_list, tag, NULL) == NULL)
469 * udev_enumerate_add_match_parent:
470 * @udev_enumerate: context
471 * @parent: parent device where to start searching
473 * Return the devices on the subtree of one given device. The parent
474 * itself is included in the list.
476 * A reference for the device is held until the udev_enumerate context
479 * Returns: 0 on success, otherwise a negative error value.
481 _public_ int udev_enumerate_add_match_parent(struct udev_enumerate *udev_enumerate, struct udev_device *parent)
483 if (udev_enumerate == NULL)
487 if (udev_enumerate->parent_match != NULL)
488 udev_device_unref(udev_enumerate->parent_match);
489 udev_enumerate->parent_match = udev_device_ref(parent);
494 * udev_enumerate_add_match_is_initialized:
495 * @udev_enumerate: context
497 * Match only devices which udev has set up already. This makes
498 * sure, that the device node permissions and context are properly set
499 * and that network devices are fully renamed.
501 * Usually, devices which are found in the kernel but not already
502 * handled by udev, have still pending events. Services should subscribe
503 * to monitor events and wait for these devices to become ready, instead
504 * of using uninitialized devices.
506 * For now, this will not affect devices which do not have a device node
507 * and are not network interfaces.
509 * Returns: 0 on success, otherwise a negative error value.
511 _public_ int udev_enumerate_add_match_is_initialized(struct udev_enumerate *udev_enumerate)
513 if (udev_enumerate == NULL)
515 udev_enumerate->match_is_initialized = true;
520 * udev_enumerate_add_match_sysname:
521 * @udev_enumerate: context
522 * @sysname: filter for the name of the device to include in the list
524 * Match only devices with a given /sys device name.
526 * Returns: 0 on success, otherwise a negative error value.
528 _public_ int udev_enumerate_add_match_sysname(struct udev_enumerate *udev_enumerate, const char *sysname)
530 if (udev_enumerate == NULL)
534 if (udev_list_entry_add(&udev_enumerate->sysname_match_list, sysname, NULL) == NULL)
539 static bool match_sysattr(struct udev_enumerate *udev_enumerate, struct udev_device *dev)
541 struct udev_list_entry *list_entry;
544 udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->sysattr_nomatch_list)) {
545 if (match_sysattr_value(dev, udev_list_entry_get_name(list_entry),
546 udev_list_entry_get_value(list_entry)))
550 if (udev_list_get_entry(&udev_enumerate->sysattr_match_list) != NULL) {
551 udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->sysattr_match_list)) {
552 /* anything that does not match, will make it FALSE */
553 if (!match_sysattr_value(dev, udev_list_entry_get_name(list_entry),
554 udev_list_entry_get_value(list_entry)))
562 static bool match_property(struct udev_enumerate *udev_enumerate, struct udev_device *dev)
564 struct udev_list_entry *list_entry;
567 /* no match always matches */
568 if (udev_list_get_entry(&udev_enumerate->properties_match_list) == NULL)
571 /* loop over matches */
572 udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->properties_match_list)) {
573 const char *match_key = udev_list_entry_get_name(list_entry);
574 const char *match_value = udev_list_entry_get_value(list_entry);
575 struct udev_list_entry *property_entry;
577 /* loop over device properties */
578 udev_list_entry_foreach(property_entry, udev_device_get_properties_list_entry(dev)) {
579 const char *dev_key = udev_list_entry_get_name(property_entry);
580 const char *dev_value = udev_list_entry_get_value(property_entry);
582 if (fnmatch(match_key, dev_key, 0) != 0)
584 if (match_value == NULL && dev_value == NULL) {
588 if (match_value == NULL || dev_value == NULL)
590 if (fnmatch(match_value, dev_value, 0) == 0) {
600 static bool match_tag(struct udev_enumerate *udev_enumerate, struct udev_device *dev)
602 struct udev_list_entry *list_entry;
604 /* no match always matches */
605 if (udev_list_get_entry(&udev_enumerate->tags_match_list) == NULL)
608 /* loop over matches */
609 udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->tags_match_list))
610 if (!udev_device_has_tag(dev, udev_list_entry_get_name(list_entry)))
616 static bool match_parent(struct udev_enumerate *udev_enumerate, struct udev_device *dev)
618 if (udev_enumerate->parent_match == NULL)
621 return startswith(udev_device_get_devpath(dev), udev_device_get_devpath(udev_enumerate->parent_match));
624 static bool match_sysname(struct udev_enumerate *udev_enumerate, const char *sysname)
626 struct udev_list_entry *list_entry;
628 if (udev_list_get_entry(&udev_enumerate->sysname_match_list) == NULL)
631 udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->sysname_match_list)) {
632 if (fnmatch(udev_list_entry_get_name(list_entry), sysname, 0) != 0)
639 static int scan_dir_and_add_devices(struct udev_enumerate *udev_enumerate,
640 const char *basedir, const char *subdir1, const char *subdir2)
642 char path[UTIL_PATH_SIZE];
649 l = util_strpcpyl(&s, sizeof(path), "/sys/", basedir, NULL);
651 l = util_strpcpyl(&s, l, "/", subdir1, NULL);
653 util_strpcpyl(&s, l, "/", subdir2, NULL);
657 for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
658 char syspath[UTIL_PATH_SIZE];
659 struct udev_device *dev;
661 if (dent->d_name[0] == '.')
664 if (!match_sysname(udev_enumerate, dent->d_name))
667 util_strscpyl(syspath, sizeof(syspath), path, "/", dent->d_name, NULL);
668 dev = udev_device_new_from_syspath(udev_enumerate->udev, syspath);
672 if (udev_enumerate->match_is_initialized) {
674 * All devices with a device node or network interfaces
675 * possibly need udev to adjust the device node permission
676 * or context, or rename the interface before it can be
677 * reliably used from other processes.
679 * For now, we can only check these types of devices, we
680 * might not store a database, and have no way to find out
681 * for all other types of devices.
683 if (!udev_device_get_is_initialized(dev) &&
684 (major(udev_device_get_devnum(dev)) > 0 || udev_device_get_ifindex(dev) > 0))
687 if (!match_parent(udev_enumerate, dev))
689 if (!match_tag(udev_enumerate, dev))
691 if (!match_property(udev_enumerate, dev))
693 if (!match_sysattr(udev_enumerate, dev))
696 syspath_add(udev_enumerate, udev_device_get_syspath(dev));
698 udev_device_unref(dev);
704 static bool match_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem)
706 struct udev_list_entry *list_entry;
708 udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->subsystem_nomatch_list)) {
709 if (fnmatch(udev_list_entry_get_name(list_entry), subsystem, 0) == 0)
712 if (udev_list_get_entry(&udev_enumerate->subsystem_match_list) != NULL) {
713 udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->subsystem_match_list)) {
714 if (fnmatch(udev_list_entry_get_name(list_entry), subsystem, 0) == 0)
722 static int scan_dir(struct udev_enumerate *udev_enumerate, const char *basedir, const char *subdir, const char *subsystem)
724 char path[UTIL_PATH_SIZE];
728 util_strscpyl(path, sizeof(path), "/sys/", basedir, NULL);
732 for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
733 if (dent->d_name[0] == '.')
735 if (!match_subsystem(udev_enumerate, subsystem != NULL ? subsystem : dent->d_name))
737 scan_dir_and_add_devices(udev_enumerate, basedir, dent->d_name, subdir);
744 * udev_enumerate_add_syspath:
745 * @udev_enumerate: context
746 * @syspath: path of a device
748 * Add a device to the list of devices, to retrieve it back sorted in dependency order.
750 * Returns: 0 on success, otherwise a negative error value.
752 _public_ int udev_enumerate_add_syspath(struct udev_enumerate *udev_enumerate, const char *syspath)
754 struct udev_device *udev_device;
756 if (udev_enumerate == NULL)
760 /* resolve to real syspath */
761 udev_device = udev_device_new_from_syspath(udev_enumerate->udev, syspath);
762 if (udev_device == NULL)
764 syspath_add(udev_enumerate, udev_device_get_syspath(udev_device));
765 udev_device_unref(udev_device);
769 static int scan_devices_tags(struct udev_enumerate *udev_enumerate)
771 struct udev_list_entry *list_entry;
773 /* scan only tagged devices, use tags reverse-index, instead of searching all devices in /sys */
774 udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_enumerate->tags_match_list)) {
777 char path[UTIL_PATH_SIZE];
779 util_strscpyl(path, sizeof(path), "/run/udev/tags/", udev_list_entry_get_name(list_entry), NULL);
783 for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
784 struct udev_device *dev;
786 if (dent->d_name[0] == '.')
789 dev = udev_device_new_from_id_filename(udev_enumerate->udev, dent->d_name);
793 if (!match_subsystem(udev_enumerate, udev_device_get_subsystem(dev)))
795 if (!match_sysname(udev_enumerate, udev_device_get_sysname(dev)))
797 if (!match_parent(udev_enumerate, dev))
799 if (!match_property(udev_enumerate, dev))
801 if (!match_sysattr(udev_enumerate, dev))
804 syspath_add(udev_enumerate, udev_device_get_syspath(dev));
806 udev_device_unref(dev);
813 static int parent_add_child(struct udev_enumerate *enumerate, const char *path)
815 struct udev_device *dev;
817 dev = udev_device_new_from_syspath(enumerate->udev, path);
821 if (!match_subsystem(enumerate, udev_device_get_subsystem(dev)))
823 if (!match_sysname(enumerate, udev_device_get_sysname(dev)))
825 if (!match_property(enumerate, dev))
827 if (!match_sysattr(enumerate, dev))
830 syspath_add(enumerate, udev_device_get_syspath(dev));
831 udev_device_unref(dev);
835 static int parent_crawl_children(struct udev_enumerate *enumerate, const char *path, int maxdepth)
844 for (dent = readdir(d); dent != NULL; dent = readdir(d)) {
847 if (dent->d_name[0] == '.')
849 if (dent->d_type != DT_DIR)
851 if (asprintf(&child, "%s/%s", path, dent->d_name) < 0)
853 parent_add_child(enumerate, child);
855 parent_crawl_children(enumerate, child, maxdepth-1);
863 static int scan_devices_children(struct udev_enumerate *enumerate)
867 path = udev_device_get_syspath(enumerate->parent_match);
868 parent_add_child(enumerate, path);
869 return parent_crawl_children(enumerate, path, 256);
872 static int scan_devices_all(struct udev_enumerate *udev_enumerate)
876 if (stat("/sys/subsystem", &statbuf) == 0) {
877 /* we have /subsystem/, forget all the old stuff */
878 scan_dir(udev_enumerate, "subsystem", "devices", NULL);
880 scan_dir(udev_enumerate, "bus", "devices", NULL);
881 scan_dir(udev_enumerate, "class", NULL, NULL);
887 * udev_enumerate_scan_devices:
888 * @udev_enumerate: udev enumeration context
890 * Scan /sys for all devices which match the given filters. No matches
891 * will return all currently available devices.
893 * Returns: 0 on success, otherwise a negative error value.
895 _public_ int udev_enumerate_scan_devices(struct udev_enumerate *udev_enumerate)
897 if (udev_enumerate == NULL)
900 /* efficiently lookup tags only, we maintain a reverse-index */
901 if (udev_list_get_entry(&udev_enumerate->tags_match_list) != NULL)
902 return scan_devices_tags(udev_enumerate);
904 /* walk the subtree of one parent device only */
905 if (udev_enumerate->parent_match != NULL)
906 return scan_devices_children(udev_enumerate);
908 /* scan devices of all subsystems */
909 return scan_devices_all(udev_enumerate);
913 * udev_enumerate_scan_subsystems:
914 * @udev_enumerate: udev enumeration context
916 * Scan /sys for all kernel subsystems, including buses, classes, drivers.
918 * Returns: 0 on success, otherwise a negative error value.
920 _public_ int udev_enumerate_scan_subsystems(struct udev_enumerate *udev_enumerate)
923 const char *subsysdir;
925 if (udev_enumerate == NULL)
928 /* all kernel modules */
929 if (match_subsystem(udev_enumerate, "module"))
930 scan_dir_and_add_devices(udev_enumerate, "module", NULL, NULL);
932 if (stat("/sys/subsystem", &statbuf) == 0)
933 subsysdir = "subsystem";
937 /* all subsystems (only buses support coldplug) */
938 if (match_subsystem(udev_enumerate, "subsystem"))
939 scan_dir_and_add_devices(udev_enumerate, subsysdir, NULL, NULL);
941 /* all subsystem drivers */
942 if (match_subsystem(udev_enumerate, "drivers"))
943 scan_dir(udev_enumerate, subsysdir, "drivers", "drivers");