diff options
Diffstat (limited to 'src/libsystemd/sd-bus/bus-objects.c')
-rw-r--r-- | src/libsystemd/sd-bus/bus-objects.c | 51 |
1 files changed, 24 insertions, 27 deletions
diff --git a/src/libsystemd/sd-bus/bus-objects.c b/src/libsystemd/sd-bus/bus-objects.c index c25293e5e9..728f20447a 100644 --- a/src/libsystemd/sd-bus/bus-objects.c +++ b/src/libsystemd/sd-bus/bus-objects.c @@ -169,11 +169,18 @@ static int add_enumerated_to_set( return 0; } +enum { + /* if set, add_subtree() works recursively */ + CHILDREN_RECURSIVE = (1U << 1), + /* if set, add_subtree() scans object-manager hierarchies recursively */ + CHILDREN_SUBHIERARCHIES = (1U << 0), +}; + static int add_subtree_to_set( sd_bus *bus, const char *prefix, struct node *n, - bool skip_subhierarchies, + unsigned int flags, Set *s, sd_bus_error *error) { @@ -205,8 +212,9 @@ static int add_subtree_to_set( if (r < 0 && r != -EEXIST) return r; - if (!skip_subhierarchies || !i->object_managers) { - r = add_subtree_to_set(bus, prefix, i, skip_subhierarchies, s, error); + if ((flags & CHILDREN_RECURSIVE) && + ((flags & CHILDREN_SUBHIERARCHIES) || !i->object_managers)) { + r = add_subtree_to_set(bus, prefix, i, flags, s, error); if (r < 0) return r; if (bus->nodes_modified) @@ -221,7 +229,7 @@ static int get_child_nodes( sd_bus *bus, const char *prefix, struct node *n, - bool skip_subhierarchies, + unsigned int flags, Set **_s, sd_bus_error *error) { @@ -237,7 +245,7 @@ static int get_child_nodes( if (!s) return -ENOMEM; - r = add_subtree_to_set(bus, prefix, n, skip_subhierarchies, s, error); + r = add_subtree_to_set(bus, prefix, n, flags, s, error); if (r < 0) { set_free_free(s); return r; @@ -750,6 +758,9 @@ static int vtable_append_all_properties( if (v->flags & SD_BUS_VTABLE_HIDDEN) continue; + if (v->flags & SD_BUS_VTABLE_PROPERTY_EXPLICIT) + continue; + r = vtable_append_one_property(bus, reply, path, c, v, userdata, error); if (r < 0) return r; @@ -904,7 +915,7 @@ static int process_introspect( assert(n); assert(found_object); - r = get_child_nodes(bus, m->path, n, false, &s, &error); + r = get_child_nodes(bus, m->path, n, 0, &s, &error); if (r < 0) return bus_maybe_reply_error(m, r, &error); if (bus->nodes_modified) @@ -1170,16 +1181,12 @@ static int process_get_managed_objects( if (require_fallback || !n->object_managers) return 0; - r = get_child_nodes(bus, m->path, n, true, &s, &error); + r = get_child_nodes(bus, m->path, n, CHILDREN_RECURSIVE, &s, &error); if (r < 0) return r; if (bus->nodes_modified) return 0; - r = set_put_strdup(s, m->path); - if (r < 0) - return r; - r = sd_bus_message_new_method_return(m, &reply); if (r < 0) return r; @@ -1571,25 +1578,14 @@ _public_ int sd_bus_add_fallback( return bus_add_object(bus, slot, true, prefix, callback, userdata); } -static unsigned long vtable_member_hash_func(const void *a, const uint8_t hash_key[HASH_KEY_SIZE]) { +static void vtable_member_hash_func(const void *a, struct siphash *state) { const struct vtable_member *m = a; - uint8_t hash_key2[HASH_KEY_SIZE]; - unsigned long ret; assert(m); - ret = string_hash_func(m->path, hash_key); - - /* Use a slightly different hash key for the interface */ - memcpy(hash_key2, hash_key, HASH_KEY_SIZE); - hash_key2[0]++; - ret ^= string_hash_func(m->interface, hash_key2); - - /* And an even different one for the member */ - hash_key2[0]++; - ret ^= string_hash_func(m->member, hash_key2); - - return ret; + string_hash_func(m->path, state); + string_hash_func(m->interface, state); + string_hash_func(m->member, state); } static int vtable_member_compare_func(const void *a, const void *b) { @@ -1745,8 +1741,9 @@ static int add_object_vtable_internal( if (!member_name_is_valid(v->x.property.member) || !signature_is_single(v->x.property.signature, false) || !(v->x.property.get || bus_type_is_basic(v->x.property.signature[0]) || streq(v->x.property.signature, "as")) || - v->flags & SD_BUS_VTABLE_METHOD_NO_REPLY || + (v->flags & SD_BUS_VTABLE_METHOD_NO_REPLY) || (!!(v->flags & SD_BUS_VTABLE_PROPERTY_CONST) + !!(v->flags & SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE) + !!(v->flags & SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION)) > 1 || + ((v->flags & SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE) && (v->flags & SD_BUS_VTABLE_PROPERTY_EXPLICIT)) || (v->flags & SD_BUS_VTABLE_UNPRIVILEGED && v->type == _SD_BUS_VTABLE_PROPERTY)) { r = -EINVAL; goto fail; |