diff options
author | David Herrmann <dh.herrmann@gmail.com> | 2014-09-17 10:32:49 +0200 |
---|---|---|
committer | David Herrmann <dh.herrmann@gmail.com> | 2014-09-17 11:01:56 +0200 |
commit | ff02f101cb7db516bf1732bb74c42cb3b6259af1 (patch) | |
tree | eebdd506b883a2009774ea7c99bfbfbff5d73331 | |
parent | 943c3f94e2f8b8b35ef6a40220bbe4c06510930c (diff) |
bus: fix error leak in bus_node_exists()
If we call into user callbacks, we must always propagate possible errors.
Fix bus_node_exists() to do that and adjust the callers (which already
partially propagated the error).
Also speed up that function by first checking for registered enumerators
and/or object-managers.
-rw-r--r-- | src/libsystemd/sd-bus/bus-objects.c | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/src/libsystemd/sd-bus/bus-objects.c b/src/libsystemd/sd-bus/bus-objects.c index ecac73a94d..0ab1119b58 100644 --- a/src/libsystemd/sd-bus/bus-objects.c +++ b/src/libsystemd/sd-bus/bus-objects.c @@ -820,7 +820,7 @@ static int property_get_all_callbacks_run( return 1; } -static bool bus_node_exists( +static int bus_node_exists( sd_bus *bus, struct node *n, const char *path, @@ -828,6 +828,7 @@ static bool bus_node_exists( struct node_vtable *c; struct node_callback *k; + int r; assert(bus); assert(n); @@ -836,11 +837,14 @@ static bool bus_node_exists( /* Tests if there's anything attached directly to this node * for the specified path */ + if (!require_fallback && (n->enumerators || n->object_managers)) + return true; + LIST_FOREACH(callbacks, k, n->callbacks) { if (require_fallback && !k->is_fallback) continue; - return true; + return 1; } LIST_FOREACH(vtables, c, n->vtables) { @@ -849,13 +853,14 @@ static bool bus_node_exists( if (require_fallback && !c->is_fallback) continue; - if (node_vtable_get_userdata(bus, path, c, NULL, &error) > 0) - return true; + r = node_vtable_get_userdata(bus, path, c, NULL, &error); + if (r != 0) + return r; if (bus->nodes_modified) - return false; + return 0; } - return !require_fallback && (n->enumerators || n->object_managers); + return 0; } static int process_introspect( @@ -938,12 +943,12 @@ static int process_introspect( /* Nothing?, let's see if we exist at all, and if not * refuse to do anything */ r = bus_node_exists(bus, n, m->path, require_fallback); - if (r < 0) - return r; - if (bus->nodes_modified) - return 0; - if (r == 0) + if (r <= 0) + goto finish; + if (bus->nodes_modified) { + r = 0; goto finish; + } } *found_object = true; @@ -1293,6 +1298,8 @@ static int object_find_and_run( r = bus_node_exists(bus, n, m->path, require_fallback); if (r < 0) return r; + if (bus->nodes_modified) + return 0; if (r > 0) *found_object = true; } |