diff options
author | David Herrmann <dh.herrmann@gmail.com> | 2014-12-30 11:37:35 +0100 |
---|---|---|
committer | David Herrmann <dh.herrmann@gmail.com> | 2014-12-30 11:37:35 +0100 |
commit | d95eb43e90f19ff0c9aaff1c5fb1a7ed9fbd89a5 (patch) | |
tree | 87325a4eaa726f00809ced8090e7cf6b38b186ae /src/libsystemd/sd-bus/test-bus-objects.c | |
parent | 7d9fcc2bf6869993e5f38d5eb183fb59e8a52816 (diff) |
bus: add sd_bus_emit_object_{added/removed}()
This implements two new helpers, discussed on systemd-devel about 1 year
ago:
sd_bus_emit_object_added()
sd_bus_emit_object_removed()
Both calls are equivalent to their respective counterpart
sd_bus_emit_interfaces_{added/removed}(), but can figure out the list of
interfaces themselves, instead of requiring the caller to provide them.
Furthermore, both calls properly deal with builtin interfaces provided via
org.freedesktop.DBus.* and alike.
Both calls simply traverse a node and all its parent nodes to figure out a
list of all interfaces registered as vtable or fallback. It then appends
each of them, similar to the interfaces_{added/removed}() helpers.
Note that interfaces_{added/removed}() runs a parent traversal for *each*
passed interface. Therefore, it can simply bail out, once it found a
parent node that implements a given interface.
With object_{added/removed}() we cannot know the registered interfaces in
advance, thus, we cannot run one traversal per node. Instead, we run a
single traversal and remember all interfaces that we added. Therefore, a
child-interface overrides all conflicting parent-interfaces. We keep a
"Set *s" context to track those while climbing up the tree.
Diffstat (limited to 'src/libsystemd/sd-bus/test-bus-objects.c')
-rw-r--r-- | src/libsystemd/sd-bus/test-bus-objects.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/libsystemd/sd-bus/test-bus-objects.c b/src/libsystemd/sd-bus/test-bus-objects.c index 06b8904f13..acf67a52b3 100644 --- a/src/libsystemd/sd-bus/test-bus-objects.c +++ b/src/libsystemd/sd-bus/test-bus-objects.c @@ -176,6 +176,28 @@ static int emit_interfaces_removed(sd_bus *bus, sd_bus_message *m, void *userdat return 1; } +static int emit_object_added(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) { + int r; + + assert_se(sd_bus_emit_object_added(bus, m->path) >= 0); + + r = sd_bus_reply_method_return(m, NULL); + assert_se(r >= 0); + + return 1; +} + +static int emit_object_removed(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) { + int r; + + assert_se(sd_bus_emit_object_removed(bus, m->path) >= 0); + + r = sd_bus_reply_method_return(m, NULL); + assert_se(r >= 0); + + return 1; +} + static const sd_bus_vtable vtable[] = { SD_BUS_VTABLE_START(0), SD_BUS_METHOD("AlterSomething", "s", "s", something_handler, 0), @@ -186,6 +208,8 @@ static const sd_bus_vtable vtable[] = { SD_BUS_METHOD("NoOperation", NULL, NULL, NULL, 0), SD_BUS_METHOD("EmitInterfacesAdded", NULL, NULL, emit_interfaces_added, 0), SD_BUS_METHOD("EmitInterfacesRemoved", NULL, NULL, emit_interfaces_removed, 0), + SD_BUS_METHOD("EmitObjectAdded", NULL, NULL, emit_object_added, 0), + SD_BUS_METHOD("EmitObjectRemoved", NULL, NULL, emit_object_removed, 0), SD_BUS_VTABLE_END }; @@ -456,6 +480,30 @@ static int client(struct context *c) { sd_bus_message_unref(reply); reply = NULL; + r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "EmitObjectAdded", &error, NULL, ""); + assert_se(r >= 0); + + r = sd_bus_process(bus, &reply); + assert_se(r > 0); + + assert_se(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.ObjectManager", "InterfacesAdded")); + bus_message_dump(reply, stdout, BUS_MESSAGE_DUMP_WITH_HEADER); + + sd_bus_message_unref(reply); + reply = NULL; + + r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "EmitObjectRemoved", &error, NULL, ""); + assert_se(r >= 0); + + r = sd_bus_process(bus, &reply); + assert_se(r > 0); + + assert_se(sd_bus_message_is_signal(reply, "org.freedesktop.DBus.ObjectManager", "InterfacesRemoved")); + bus_message_dump(reply, stdout, BUS_MESSAGE_DUMP_WITH_HEADER); + + sd_bus_message_unref(reply); + reply = NULL; + r = sd_bus_call_method(bus, "org.freedesktop.systemd.test", "/foo", "org.freedesktop.systemd.test", "Exit", &error, NULL, ""); assert_se(r >= 0); |