diff options
author | Lennart Poettering <lennart@poettering.net> | 2013-10-11 06:10:15 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2013-10-11 06:10:15 +0200 |
commit | adcdb3747609962881301ed19636002dd34c05a0 (patch) | |
tree | c3e3e5f80205bef89931e49f03ac2e0f55300098 | |
parent | 62b5c2aec12e6a3d305445ee1a88bc18ca0a1548 (diff) |
bus: when NULL is specified as property callback, automatically handle serialization on Get()
-rw-r--r-- | src/libsystemd-bus/bus-type.c | 1 | ||||
-rw-r--r-- | src/libsystemd-bus/sd-bus.c | 58 | ||||
-rw-r--r-- | src/libsystemd-bus/test-bus-introspect.c | 6 | ||||
-rw-r--r-- | src/libsystemd-bus/test-bus-objects.c | 17 | ||||
-rw-r--r-- | src/systemd/sd-bus-vtable.h | 2 |
5 files changed, 65 insertions, 19 deletions
diff --git a/src/libsystemd-bus/bus-type.c b/src/libsystemd-bus/bus-type.c index 6354c84f2c..b7914d15d3 100644 --- a/src/libsystemd-bus/bus-type.c +++ b/src/libsystemd-bus/bus-type.c @@ -108,7 +108,6 @@ bool bus_type_is_trivial(char c) { return !!memchr(valid, c, sizeof(valid)); } - bool bus_type_is_container(char c) { static const char valid[] = { SD_BUS_TYPE_ARRAY, diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c index 11194af007..1d8d569429 100644 --- a/src/libsystemd-bus/sd-bus.c +++ b/src/libsystemd-bus/sd-bus.c @@ -2103,6 +2103,46 @@ static int method_callbacks_run( return c->vtable->method.handler(bus, m, u); } +static int invoke_property_get( + sd_bus *bus, + const sd_bus_vtable *v, + const char *path, + const char *interface, + const char *property, + sd_bus_message *m, + sd_bus_error *error, + void *userdata) { + + int r; + void *p; + + assert(bus); + assert(v); + + if (v->property.get) + return v->property.get(bus, path, interface, property, m, error, userdata); + + /* Automatic handling if no callback is defined. */ + + switch (v->property.signature[0]) { + + case SD_BUS_TYPE_STRING: + case SD_BUS_TYPE_OBJECT_PATH: + case SD_BUS_TYPE_SIGNATURE: + p = *(char**) userdata; + break; + + default: + p = userdata; + } + + r = sd_bus_message_append_basic(m, v->property.signature[0], p); + if (r < 0) + return r; + + return 1; +} + static int property_get_set_callbacks_run( sd_bus *bus, sd_bus_message *m, @@ -2140,12 +2180,9 @@ static int property_get_set_callbacks_run( if (r < 0) return r; - if (c->vtable->property.get) { - r = c->vtable->property.get(bus, m->path, c->interface, c->member, reply, &error, u); - if (r < 0) - return r; - } else - assert_not_reached("automatic properties not supported yet"); + r = invoke_property_get(bus, c->vtable, m->path, c->interface, c->member, reply, &error, u); + if (r < 0) + return r; if (sd_bus_error_is_set(&error)) { r = sd_bus_reply_method_error(bus, m, &error); @@ -2226,7 +2263,7 @@ static int vtable_append_all_properties( if (r < 0) return r; - r = v->property.get(bus, path, c->interface, v->property.member, reply, error, vtable_property_convert_userdata(v, userdata)); + r = invoke_property_get(bus, v, path, c->interface, v->property.member, reply, error, vtable_property_convert_userdata(v, userdata)); if (r < 0) return r; @@ -3588,7 +3625,7 @@ static void free_node_vtable(sd_bus *bus, struct node_vtable *w) { if (w->interface && w->node && w->vtable) { const sd_bus_vtable *v; - for (v = w->vtable; v->type != _SD_BUS_VTABLE_END; w++) { + for (v = w->vtable; v->type != _SD_BUS_VTABLE_END; v++) { struct vtable_member *x = NULL; switch (v->type) { @@ -3757,6 +3794,7 @@ static int add_object_vtable_internal( if (!member_name_is_valid(v->property.member) || !signature_is_single(v->property.signature, false) || + !(v->property.get || bus_type_is_basic(v->property.signature[0])) || v->flags & SD_BUS_VTABLE_METHOD_NO_REPLY || (v->flags & SD_BUS_VTABLE_PROPERTY_INVALIDATE_ONLY && !(v->flags & SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE))) { r = -EINVAL; @@ -3809,7 +3847,7 @@ fail: free_node_vtable(bus, c); bus_node_gc(bus, n); - return 0; + return r; } static int remove_object_vtable_internal( @@ -4048,7 +4086,7 @@ static int emit_properties_changed_on_interface( if (r < 0) return r; - r = v->vtable->property.get(bus, m->path, interface, *property, m, &error, vtable_property_convert_userdata(v->vtable, u)); + r = invoke_property_get(bus, v->vtable, m->path, interface, *property, m, &error, vtable_property_convert_userdata(v->vtable, u)); if (r < 0) return r; diff --git a/src/libsystemd-bus/test-bus-introspect.c b/src/libsystemd-bus/test-bus-introspect.c index ea26cdd101..ae41618647 100644 --- a/src/libsystemd-bus/test-bus-introspect.c +++ b/src/libsystemd-bus/test-bus-introspect.c @@ -33,9 +33,9 @@ static int prop_set(sd_bus *bus, const char *path, const char *interface, const static const sd_bus_vtable vtable[] = { SD_BUS_VTABLE_START(0), - SD_BUS_METHOD("Hello", "ssas", "a(uu)", 0, NULL), - SD_BUS_METHOD("DeprecatedHello", "", "", SD_BUS_VTABLE_DEPRECATED, NULL), - SD_BUS_METHOD("DeprecatedHelloNoReply", "", "", SD_BUS_VTABLE_DEPRECATED|SD_BUS_VTABLE_METHOD_NO_REPLY, NULL), + SD_BUS_METHOD("Hello", "ssas", "a(uu)", NULL, 0), + SD_BUS_METHOD("DeprecatedHello", "", "", NULL, SD_BUS_VTABLE_DEPRECATED), + SD_BUS_METHOD("DeprecatedHelloNoReply", "", "", NULL, SD_BUS_VTABLE_DEPRECATED|SD_BUS_VTABLE_METHOD_NO_REPLY), SD_BUS_SIGNAL("Wowza", "sss", 0), SD_BUS_SIGNAL("DeprecatedWowza", "ut", SD_BUS_VTABLE_DEPRECATED), SD_BUS_WRITABLE_PROPERTY("AProperty", "s", prop_get, prop_set, 0, 0), diff --git a/src/libsystemd-bus/test-bus-objects.c b/src/libsystemd-bus/test-bus-objects.c index b4facda04b..06947a2c18 100644 --- a/src/libsystemd-bus/test-bus-objects.c +++ b/src/libsystemd-bus/test-bus-objects.c @@ -38,7 +38,9 @@ * * Add in: * - * automatic properties + * automatic properties for Set() + * automatic NULL method + * allow NULL as signatures in vtable * node hierarchy updates during dispatching * emit_interfaces_added/emit_interfaces_removed * @@ -48,6 +50,8 @@ struct context { int fds[2]; bool quit; char *something; + const char *automatic_string_property; + uint32_t automatic_integer_property; }; static int something_handler(sd_bus *bus, sd_bus_message *m, void *userdata) { @@ -148,15 +152,17 @@ static int notify_test(sd_bus *bus, sd_bus_message *m, void *userdata) { static const sd_bus_vtable vtable[] = { SD_BUS_VTABLE_START(0), - SD_BUS_METHOD("AlterSomething", "s", "s", 0, something_handler), - SD_BUS_METHOD("Exit", "", "", 0, exit_handler), + SD_BUS_METHOD("AlterSomething", "s", "s", something_handler, 0), + SD_BUS_METHOD("Exit", "", "", exit_handler, 0), SD_BUS_WRITABLE_PROPERTY("Something", "s", get_handler, set_handler, 0, 0), + SD_BUS_PROPERTY("AutomaticStringProperty", "s", NULL, offsetof(struct context, automatic_string_property), 0), + SD_BUS_PROPERTY("AutomaticIntegerProperty", "u", NULL, offsetof(struct context, automatic_integer_property), 0), SD_BUS_VTABLE_END }; static const sd_bus_vtable vtable2[] = { SD_BUS_VTABLE_START(0), - SD_BUS_METHOD("NotifyTest", "", "", 0, notify_test), + SD_BUS_METHOD("NotifyTest", "", "", notify_test, 0), SD_BUS_PROPERTY("Value", "s", value_handler, 10, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), SD_BUS_VTABLE_END }; @@ -384,6 +390,9 @@ int main(int argc, char *argv[]) { zero(c); + c.automatic_integer_property = 4711; + c.automatic_string_property = "dudeldu"; + assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, c.fds) >= 0); r = pthread_create(&s, NULL, server, &c); diff --git a/src/systemd/sd-bus-vtable.h b/src/systemd/sd-bus-vtable.h index a1f078e540..5203bf1a9b 100644 --- a/src/systemd/sd-bus-vtable.h +++ b/src/systemd/sd-bus-vtable.h @@ -80,7 +80,7 @@ struct sd_bus_vtable { .start.element_size = sizeof(sd_bus_vtable), \ } -#define SD_BUS_METHOD(_member, _signature, _result, _flags, _handler) \ +#define SD_BUS_METHOD(_member, _signature, _result, _handler, _flags) \ { \ .type = _SD_BUS_VTABLE_METHOD, \ .flags = _flags, \ |