Lines Matching refs:enumerator
24 #include "device-enumerator-private.h"
62 _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *enumerator = NULL;
66 enumerator = new0(sd_device_enumerator, 1);
67 if (!enumerator)
70 enumerator->n_ref = 1;
71 enumerator->type = _DEVICE_ENUMERATION_TYPE_INVALID;
73 *ret = enumerator;
74 enumerator = NULL;
79 _public_ sd_device_enumerator *sd_device_enumerator_ref(sd_device_enumerator *enumerator) {
80 assert_return(enumerator, NULL);
82 assert_se((++ enumerator->n_ref) >= 2);
84 return enumerator;
87 _public_ sd_device_enumerator *sd_device_enumerator_unref(sd_device_enumerator *enumerator) {
88 if (enumerator && (-- enumerator->n_ref) == 0) {
91 while ((device = prioq_pop(enumerator->devices)))
94 prioq_free(enumerator->devices);
96 set_free_free(enumerator->match_subsystem);
97 set_free_free(enumerator->nomatch_subsystem);
98 hashmap_free_free_free(enumerator->match_sysattr);
99 hashmap_free_free_free(enumerator->nomatch_sysattr);
100 hashmap_free_free_free(enumerator->match_property);
101 set_free_free(enumerator->match_sysname);
102 set_free_free(enumerator->match_tag);
103 sd_device_unref(enumerator->match_parent);
105 free(enumerator);
111 _public_ int sd_device_enumerator_add_match_subsystem(sd_device_enumerator *enumerator, const char *subsystem, int match) {
115 assert_return(enumerator, -EINVAL);
119 set = &enumerator->match_subsystem;
121 set = &enumerator->nomatch_subsystem;
131 enumerator->scan_uptodate = false;
136 _public_ int sd_device_enumerator_add_match_sysattr(sd_device_enumerator *enumerator, const char *_sysattr, const char *_value, int match) {
141 assert_return(enumerator, -EINVAL);
145 hashmap = &enumerator->match_sysattr;
147 hashmap = &enumerator->nomatch_sysattr;
170 enumerator->scan_uptodate = false;
175 _public_ int sd_device_enumerator_add_match_property(sd_device_enumerator *enumerator, const char *_property, const char *_value) {
179 assert_return(enumerator, -EINVAL);
182 r = hashmap_ensure_allocated(&enumerator->match_property, NULL);
196 r = hashmap_put(enumerator->match_property, property, value);
203 enumerator->scan_uptodate = false;
208 _public_ int sd_device_enumerator_add_match_sysname(sd_device_enumerator *enumerator, const char *sysname) {
211 assert_return(enumerator, -EINVAL);
214 r = set_ensure_allocated(&enumerator->match_sysname, NULL);
218 r = set_put_strdup(enumerator->match_sysname, sysname);
222 enumerator->scan_uptodate = false;
227 _public_ int sd_device_enumerator_add_match_tag(sd_device_enumerator *enumerator, const char *tag) {
230 assert_return(enumerator, -EINVAL);
233 r = set_ensure_allocated(&enumerator->match_tag, NULL);
237 r = set_put_strdup(enumerator->match_tag, tag);
241 enumerator->scan_uptodate = false;
246 _public_ int sd_device_enumerator_add_match_parent(sd_device_enumerator *enumerator, sd_device *parent) {
247 assert_return(enumerator, -EINVAL);
250 sd_device_unref(enumerator->match_parent);
251 enumerator->match_parent = sd_device_ref(parent);
253 enumerator->scan_uptodate = false;
258 _public_ int sd_device_enumerator_allow_uninitialized(sd_device_enumerator *enumerator) {
259 assert_return(enumerator, -EINVAL);
261 enumerator->match_allow_uninitialized = true;
263 enumerator->scan_uptodate = false;
268 int device_enumerator_add_match_is_initialized(sd_device_enumerator *enumerator) {
269 assert_return(enumerator, -EINVAL);
271 enumerator->match_allow_uninitialized = false;
273 enumerator->scan_uptodate = false;
328 int device_enumerator_add_device(sd_device_enumerator *enumerator, sd_device *device) {
331 assert_return(enumerator, -EINVAL);
334 r = prioq_ensure_allocated(&enumerator->devices, device_compare);
338 r = prioq_put(enumerator->devices, device, NULL);
367 static bool match_sysattr(sd_device_enumerator *enumerator, sd_device *device) {
372 assert(enumerator);
375 HASHMAP_FOREACH_KEY(value, sysattr, enumerator->nomatch_sysattr, i)
379 HASHMAP_FOREACH_KEY(value, sysattr, enumerator->match_sysattr, i)
386 static bool match_property(sd_device_enumerator *enumerator, sd_device *device) {
391 assert(enumerator);
394 if (hashmap_isempty(enumerator->match_property))
397 HASHMAP_FOREACH_KEY(value, property, enumerator->match_property, i) {
418 static bool match_tag(sd_device_enumerator *enumerator, sd_device *device) {
422 assert(enumerator);
425 SET_FOREACH(tag, enumerator->match_tag, i)
432 static bool match_parent(sd_device_enumerator *enumerator, sd_device *device) {
436 assert(enumerator);
439 if (!enumerator->match_parent)
442 r = sd_device_get_devpath(enumerator->match_parent, &devpath);
451 static bool match_sysname(sd_device_enumerator *enumerator, const char *sysname) {
455 assert(enumerator);
458 if (set_isempty(enumerator->match_sysname))
461 SET_FOREACH(sysname_match, enumerator->match_sysname, i)
468 static int enumerator_scan_dir_and_add_devices(sd_device_enumerator *enumerator, const char *basedir, const char *subdir1, const char *subdir2) {
474 assert(enumerator);
498 if (!match_sysname(enumerator, dent->d_name))
540 if (!enumerator->match_allow_uninitialized &&
545 if (!match_parent(enumerator, device))
548 if (!match_tag(enumerator, device))
551 if (!match_property(enumerator, device))
554 if (!match_sysattr(enumerator, device))
557 k = device_enumerator_add_device(enumerator, device);
565 static bool match_subsystem(sd_device_enumerator *enumerator, const char *subsystem) {
569 assert(enumerator);
574 SET_FOREACH(subsystem_match, enumerator->nomatch_subsystem, i)
578 if (set_isempty(enumerator->match_subsystem))
581 SET_FOREACH(subsystem_match, enumerator->match_subsystem, i)
588 static int enumerator_scan_dir(sd_device_enumerator *enumerator, const char *basedir, const char *subdir, const char *subsystem) {
600 log_debug(" device-enumerator: scanning %s", path);
608 if (!match_subsystem(enumerator, subsystem ? : dent->d_name))
611 k = enumerator_scan_dir_and_add_devices(enumerator, basedir, dent->d_name, subdir);
619 static int enumerator_scan_devices_tag(sd_device_enumerator *enumerator, const char *tag) {
625 assert(enumerator);
635 log_error("sd-device-enumerator: could not open tags directory %s: %m", path);
665 if (!match_subsystem(enumerator, subsystem))
674 if (!match_sysname(enumerator, sysname))
677 if (!match_parent(enumerator, device))
680 if (!match_property(enumerator, device))
683 if (!match_sysattr(enumerator, device))
686 k = device_enumerator_add_device(enumerator, device);
696 static int enumerator_scan_devices_tags(sd_device_enumerator *enumerator) {
701 assert(enumerator);
703 SET_FOREACH(tag, enumerator->match_tag, i) {
704 r = enumerator_scan_devices_tag(enumerator, tag);
712 static int parent_add_child(sd_device_enumerator *enumerator, const char *path) {
730 if (!match_subsystem(enumerator, subsystem))
737 if (!match_sysname(enumerator, sysname))
740 if (!match_property(enumerator, device))
743 if (!match_sysattr(enumerator, device))
746 r = device_enumerator_add_device(enumerator, device);
753 static int parent_crawl_children(sd_device_enumerator *enumerator, const char *path, unsigned maxdepth) {
778 k = parent_add_child(enumerator, child);
783 parent_crawl_children(enumerator, child, maxdepth - 1);
791 static int enumerator_scan_devices_children(sd_device_enumerator *enumerator) {
795 r = sd_device_get_syspath(enumerator->match_parent, &path);
799 k = parent_add_child(enumerator, path);
803 k = parent_crawl_children(enumerator, path, DEVICE_ENUMERATE_MAX_DEPTH);
810 static int enumerator_scan_devices_all(sd_device_enumerator *enumerator) {
813 log_debug("device-enumerator: scan all dirs");
817 r = enumerator_scan_dir(enumerator, "subsystem", "devices", NULL);
819 return log_debug_errno(r, "device-enumerator: failed to scan /sys/subsystem: %m");
823 k = enumerator_scan_dir(enumerator, "bus", "devices", NULL);
825 log_debug_errno(k, "device-enumerator: failed to scan /sys/bus: %m");
829 k = enumerator_scan_dir(enumerator, "class", NULL, NULL);
831 log_debug_errno(k, "device-enumerator: failed to scan /sys/class: %m");
839 int device_enumerator_scan_devices(sd_device_enumerator *enumerator) {
843 assert(enumerator);
845 if (enumerator->scan_uptodate &&
846 enumerator->type == DEVICE_ENUMERATION_TYPE_DEVICES)
849 while ((device = prioq_pop(enumerator->devices)))
852 if (!set_isempty(enumerator->match_tag)) {
853 r = enumerator_scan_devices_tags(enumerator);
856 } else if (enumerator->match_parent) {
857 r = enumerator_scan_devices_children(enumerator);
861 r = enumerator_scan_devices_all(enumerator);
866 enumerator->scan_uptodate = true;
871 _public_ sd_device *sd_device_enumerator_get_device_first(sd_device_enumerator *enumerator) {
874 assert_return(enumerator, NULL);
876 r = device_enumerator_scan_devices(enumerator);
880 enumerator->type = DEVICE_ENUMERATION_TYPE_DEVICES;
882 return prioq_peek(enumerator->devices);
885 _public_ sd_device *sd_device_enumerator_get_device_next(sd_device_enumerator *enumerator) {
886 assert_return(enumerator, NULL);
888 if (!enumerator->scan_uptodate ||
889 enumerator->type != DEVICE_ENUMERATION_TYPE_DEVICES)
892 sd_device_unref(prioq_pop(enumerator->devices));
894 return prioq_peek(enumerator->devices);
897 int device_enumerator_scan_subsystems(sd_device_enumerator *enumerator) {
902 assert(enumerator);
904 if (enumerator->scan_uptodate &&
905 enumerator->type == DEVICE_ENUMERATION_TYPE_SUBSYSTEMS)
908 while ((device = prioq_pop(enumerator->devices)))
912 if (match_subsystem(enumerator, "module")) {
913 k = enumerator_scan_dir_and_add_devices(enumerator, "module", NULL, NULL);
915 log_debug_errno(k, "device-enumerator: failed to scan modules: %m");
926 if (match_subsystem(enumerator, "subsystem")) {
927 k = enumerator_scan_dir_and_add_devices(enumerator, subsysdir, NULL, NULL);
929 log_debug_errno(k, "device-enumerator: failed to scan subsystems: %m");
935 if (match_subsystem(enumerator, "drivers")) {
936 k = enumerator_scan_dir(enumerator, subsysdir, "drivers", "drivers");
938 log_debug_errno(k, "device-enumerator: failed to scan drivers: %m");
943 enumerator->scan_uptodate = true;
948 _public_ sd_device *sd_device_enumerator_get_subsystem_first(sd_device_enumerator *enumerator) {
951 assert_return(enumerator, NULL);
953 r = device_enumerator_scan_subsystems(enumerator);
957 enumerator->type = DEVICE_ENUMERATION_TYPE_SUBSYSTEMS;
959 return prioq_peek(enumerator->devices);
962 _public_ sd_device *sd_device_enumerator_get_subsystem_next(sd_device_enumerator *enumerator) {
963 assert_return(enumerator, NULL);
965 if (enumerator->scan_uptodate ||
966 enumerator->type != DEVICE_ENUMERATION_TYPE_SUBSYSTEMS)
969 sd_device_unref(prioq_pop(enumerator->devices));
971 return prioq_peek(enumerator->devices);
974 sd_device *device_enumerator_get_first(sd_device_enumerator *enumerator) {
975 assert_return(enumerator, NULL);
977 return prioq_peek(enumerator->devices);
980 sd_device *device_enumerator_get_next(sd_device_enumerator *enumerator) {
981 assert_return(enumerator, NULL);
983 sd_device_unref(prioq_pop(enumerator->devices));
985 return prioq_peek(enumerator->devices);