summaryrefslogtreecommitdiff
path: root/src/libsystemd-bus/bus-message.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2013-10-09 02:37:10 +0200
committerLennart Poettering <lennart@poettering.net>2013-10-09 02:40:07 +0200
commit29ddb38fea134c6132e4f2dd608e9da3871eaebe (patch)
treea3683f3d8064f37efe6d7bb9b454d8a8c81f38d5 /src/libsystemd-bus/bus-message.c
parent8d1a28020409ee4afea6ef8c1c4d3522a209284e (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.c81
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;
+}