static int foreach_property(const uint32_t off, void (*propfn)(const prop_info *pi, void *cookie), void *cookie) { prop_bt *trie = reinterpret_cast<prop_bt*>(to_prop_obj(off)); if (!trie) return -1; if (trie->left) { const int err = foreach_property(trie->left, propfn, cookie); if (err < 0) return -1; } if (trie->prop) { prop_info *info = reinterpret_cast<prop_info*>(to_prop_obj(trie->prop)); if (!info) return -1; propfn(info, cookie); } if (trie->children) { const int err = foreach_property(trie->children, propfn, cookie); if (err < 0) return -1; } if (trie->right) { const int err = foreach_property(trie->right, propfn, cookie); if (err < 0) return -1; } return 0; }
bool prop_area::foreach_property(prop_bt *const trie, void (*propfn)(const prop_info *pi, void *cookie), void *cookie) { if (!trie) return false; uint_least32_t left_offset = atomic_load_explicit(&trie->left, memory_order_relaxed); if (left_offset != 0) { const int err = foreach_property(to_prop_bt(&trie->left), propfn, cookie); if (err < 0) return false; } uint_least32_t prop_offset = atomic_load_explicit(&trie->prop, memory_order_relaxed); if (prop_offset != 0) { prop_info *info = to_prop_info(&trie->prop); if (!info) return false; propfn(info, cookie); } uint_least32_t children_offset = atomic_load_explicit(&trie->children, memory_order_relaxed); if (children_offset != 0) { const int err = foreach_property(to_prop_bt(&trie->children), propfn, cookie); if (err < 0) return false; } uint_least32_t right_offset = atomic_load_explicit(&trie->right, memory_order_relaxed); if (right_offset != 0) { const int err = foreach_property(to_prop_bt(&trie->right), propfn, cookie); if (err < 0) return false; } return true; }
int property_list(void (*propfn)(const char *key, const char *value, void *cookie), void *cookie) { char name[PROP_NAME_MAX]; char value[PROP_VALUE_MAX]; const prop_info *pi; unsigned n; for(n = 0; (pi = __system_property_find_nth(n)); n++) { __system_property_read(pi, name, value); propfn(name, value, cookie); } return 0; }
static struct property_vector* find_all_properties_raw(void) { for (;;) { SCOPED_RESLIST(rl); struct find_all_properties_context ctx = { .pv = property_vector_new(), .oom = false, }; if (property_foreach(find_all_properties_propfn, &ctx) == 1) continue; if (ctx.oom) die_oom(); reslist_xfer(rl->parent, rl); property_vector_sort(ctx.pv); return ctx.pv; } } static void property_vector_swap(struct property_vector* a, struct property_vector* b) { struct property_vector tmp = *a; *a = *b; *b = tmp; } static bool property_vector_equal(const struct property_vector* a, const struct property_vector* b) { return a->size == b->size && memcmp(a->props, b->props, a->size * sizeof (a->props[0])) == 0; } static struct property_vector* find_all_properties(void) { struct property_vector* pv1 = find_all_properties_raw(); for (;;) { SCOPED_RESLIST(pv); struct property_vector* pv2 = find_all_properties_raw(); if (property_vector_equal(pv1, pv2)) return pv1; property_vector_swap(pv1, pv2); } } static int compat_property_foreach( void (*propfn)(const prop_info *pi, void *cookie), void *cookie) { find_symbol_in_libc("__system_property_find_nth", &property_find_nth); if (property_find_nth == NULL) die(EINVAL, "no property-enumeration functions available"); unsigned propno = 0; for (;;) { const prop_info* pi = property_find_nth(propno++); if (pi == NULL) break; propfn(pi, cookie); } return 0; }