diff options
author | Lennart Poettering <lennart@poettering.net> | 2013-10-09 02:37:10 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2013-10-09 02:40:07 +0200 |
commit | 29ddb38fea134c6132e4f2dd608e9da3871eaebe (patch) | |
tree | a3683f3d8064f37efe6d7bb9b454d8a8c81f38d5 /src/libsystemd-bus/bus-message.c | |
parent | 8d1a28020409ee4afea6ef8c1c4d3522a209284e (diff) |
libsystemd-bus: add lightweight object vtable implementation for exposing objects on the bus
This adds a lightweight scheme how to define interfaces in static fixed
arrays which then can be easily registered on a bus connection. This
makes it much easier to write bus services.
This automatically handles implementation of the Properties,
ObjectManager, and Introspection bus interfaces.
Diffstat (limited to 'src/libsystemd-bus/bus-message.c')
-rw-r--r-- | src/libsystemd-bus/bus-message.c | 81 |
1 files changed, 75 insertions, 6 deletions
diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c index 760a148fad..2cf1a7a538 100644 --- a/src/libsystemd-bus/bus-message.c +++ b/src/libsystemd-bus/bus-message.c @@ -496,9 +496,13 @@ int sd_bus_message_new_method_call( sd_bus_message *t; int r; - if (!path) + if (destination && !service_name_is_valid(destination)) return -EINVAL; - if (!member) + if (!object_path_is_valid(path)) + return -EINVAL; + if (interface && !interface_name_is_valid(interface)) + return -EINVAL; + if (!member_name_is_valid(member)) return -EINVAL; if (!m) return -EINVAL; @@ -627,6 +631,58 @@ fail: return r; } +int sd_bus_message_new_method_errorf( + sd_bus *bus, + sd_bus_message *call, + sd_bus_message **m, + const char *name, + const char *format, + ...) { + + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + sd_bus_message *t; + va_list ap; + int r; + + if (!name) + return -EINVAL; + if (!m) + return -EINVAL; + + r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t); + if (r < 0) + return r; + + r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, name, &t->error.name); + if (r < 0) + goto fail; + + if (format) { + _cleanup_free_ char *message = NULL; + + va_start(ap, format); + r = vasprintf(&message, format, ap); + va_end(ap); + + if (r < 0) { + r = -ENOMEM; + goto fail; + } + + r = message_append_basic(t, SD_BUS_TYPE_STRING, message, (const void**) &t->error.message); + if (r < 0) + goto fail; + } + + *m = t; + return 0; + +fail: + message_free(t); + return r; +} + + int bus_message_new_synthetic_error( sd_bus *bus, uint64_t serial, @@ -1558,7 +1614,7 @@ static int bus_message_open_array( assert(contents); assert(array_size); - if (!signature_is_single(contents)) + if (!signature_is_single(contents, true)) return -EINVAL; alignment = bus_type_get_alignment(contents[0]); @@ -1629,7 +1685,7 @@ static int bus_message_open_variant( assert(c); assert(contents); - if (!signature_is_single(contents)) + if (!signature_is_single(contents, false)) return -EINVAL; if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN) @@ -2704,7 +2760,7 @@ static int bus_message_enter_array( assert(contents); assert(array_size); - if (!signature_is_single(contents)) + if (!signature_is_single(contents, true)) return -EINVAL; alignment = bus_type_get_alignment(contents[0]); @@ -2758,7 +2814,7 @@ static int bus_message_enter_variant( assert(c); assert(contents); - if (!signature_is_single(contents)) + if (!signature_is_single(contents, false)) return -EINVAL; if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN) @@ -4290,3 +4346,16 @@ int bus_message_to_errno(sd_bus_message *m) { return bus_error_to_errno(&m->error); } + +int sd_bus_message_get_signature(sd_bus_message *m, int complete, const char **signature) { + struct bus_container *c; + + if (!m) + return -EINVAL; + if (!signature) + return -EINVAL; + + c = complete ? &m->root_container : message_get_container(m); + *signature = c->signature ?: ""; + return 0; +} |