[systemd-commits] src/libsystemd-bus src/systemd

Lennart Poettering lennart at kemper.freedesktop.org
Thu Oct 10 21:11:00 PDT 2013


 src/libsystemd-bus/bus-type.c            |    1 
 src/libsystemd-bus/sd-bus.c              |   58 +++++++++++++++++++++++++------
 src/libsystemd-bus/test-bus-introspect.c |    6 +--
 src/libsystemd-bus/test-bus-objects.c    |   17 ++++++---
 src/systemd/sd-bus-vtable.h              |    2 -
 5 files changed, 65 insertions(+), 19 deletions(-)

New commits:
commit adcdb3747609962881301ed19636002dd34c05a0
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Oct 11 06:10:15 2013 +0200

    bus: when NULL is specified as property callback, automatically handle serialization on Get()

diff --git a/src/libsystemd-bus/bus-type.c b/src/libsystemd-bus/bus-type.c
index 6354c84..b7914d1 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 11194af..1d8d569 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 ea26cdd..ae41618 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 b4facda..06947a2 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 a1f078e..5203bf1 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,                                        \



More information about the systemd-commits mailing list