summaryrefslogtreecommitdiff
path: root/src/libsystemd-bus
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2013-11-21 19:34:37 +0100
committerLennart Poettering <lennart@poettering.net>2013-11-21 21:12:36 +0100
commitebcf1f97de4f6b1580ae55eb56b1a3939fe6b602 (patch)
treedef5185990acebac842ed8fca253531d88897a4a /src/libsystemd-bus
parent0ccad099d4c08dc5a16c87cdd6eefc05e9d4b670 (diff)
bus: rework message handlers to always take an error argument
Message handler callbacks can be simplified drastically if the dispatcher automatically replies to method calls if errors are returned. Thus: add an sd_bus_error argument to all message handlers. When we dispatch a message handler and it returns negative or a set sd_bus_error we send this as message error back to the client. This means errors returned by handlers by default are given back to clients instead of rippling all the way up to the event loop, which is desirable to make things robust. As a side-effect we can now easily turn the SELinux checks into normal function calls, since the method call dispatcher will generate the right error replies automatically now. Also, make sure we always pass the error structure to all property and method handlers as last argument to follow the usual style of passing variables for return values as last argument.
Diffstat (limited to 'src/libsystemd-bus')
-rw-r--r--src/libsystemd-bus/bus-match.c7
-rw-r--r--src/libsystemd-bus/bus-message.c2
-rw-r--r--src/libsystemd-bus/bus-objects.c100
-rw-r--r--src/libsystemd-bus/bus-util.c161
-rw-r--r--src/libsystemd-bus/bus-util.h16
-rw-r--r--src/libsystemd-bus/sd-bus.c26
-rw-r--r--src/libsystemd-bus/test-bus-chat.c6
-rw-r--r--src/libsystemd-bus/test-bus-introspect.c4
-rw-r--r--src/libsystemd-bus/test-bus-match.c2
-rw-r--r--src/libsystemd-bus/test-bus-objects.c20
10 files changed, 191 insertions, 153 deletions
diff --git a/src/libsystemd-bus/bus-match.c b/src/libsystemd-bus/bus-match.c
index 61b8a5cd88..f7fca5f573 100644
--- a/src/libsystemd-bus/bus-match.c
+++ b/src/libsystemd-bus/bus-match.c
@@ -22,6 +22,8 @@
#include "bus-internal.h"
#include "bus-message.h"
#include "bus-match.h"
+#include "bus-error.h"
+#include "bus-util.h"
/* Example:
*
@@ -272,7 +274,10 @@ int bus_match_run(
/* Run the callback. And then invoke siblings. */
if (node->leaf.callback) {
- r = node->leaf.callback(bus, m, node->leaf.userdata);
+ _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
+
+ r = node->leaf.callback(bus, m, node->leaf.userdata, &error_buffer);
+ r = bus_maybe_reply_error(m, r, &error_buffer);
if (r != 0)
return r;
}
diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c
index f698b2ee99..a0e4e2cbe2 100644
--- a/src/libsystemd-bus/bus-message.c
+++ b/src/libsystemd-bus/bus-message.c
@@ -2133,7 +2133,7 @@ int bus_message_append_ap(
return r;
}
- return 0;
+ return 1;
}
_public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
diff --git a/src/libsystemd-bus/bus-objects.c b/src/libsystemd-bus/bus-objects.c
index d9be3ddbfc..8413023d6f 100644
--- a/src/libsystemd-bus/bus-objects.c
+++ b/src/libsystemd-bus/bus-objects.c
@@ -223,6 +223,8 @@ static int node_callbacks_run(
assert(found_object);
LIST_FOREACH(callbacks, c, first) {
+ _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
+
if (bus->nodes_modified)
return 0;
@@ -240,7 +242,8 @@ static int node_callbacks_run(
if (r < 0)
return r;
- r = c->callback(bus, m, c->userdata);
+ r = c->callback(bus, m, c->userdata, &error_buffer);
+ r = bus_maybe_reply_error(m, r, &error_buffer);
if (r != 0)
return r;
}
@@ -299,8 +302,13 @@ static int method_callbacks_run(
return 1;
}
- if (c->vtable->x.method.handler)
- return c->vtable->x.method.handler(bus, m, u);
+ if (c->vtable->x.method.handler) {
+ _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
+
+ r = c->vtable->x.method.handler(bus, m, u, &error_buffer);
+
+ return bus_maybe_reply_error(m, r, &error_buffer);
+ }
/* If the method callback is NULL, make this a successful NOP */
r = sd_bus_reply_method_return(m, NULL);
@@ -316,9 +324,9 @@ static int invoke_property_get(
const char *path,
const char *interface,
const char *property,
- sd_bus_message *m,
- sd_bus_error *error,
- void *userdata) {
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
const void *p;
@@ -327,15 +335,15 @@ static int invoke_property_get(
assert(path);
assert(interface);
assert(property);
- assert(m);
+ assert(reply);
if (v->x.property.get)
- return v->x.property.get(bus, path, interface, property, m, error, userdata);
+ return v->x.property.get(bus, path, interface, property, reply, userdata, error);
/* Automatic handling if no callback is defined. */
if (streq(v->x.property.signature, "as"))
- return sd_bus_message_append_strv(m, *(char***) userdata);
+ return sd_bus_message_append_strv(reply, *(char***) userdata);
assert(signature_is_single(v->x.property.signature, false));
assert(bus_type_is_basic(v->x.property.signature[0]));
@@ -357,7 +365,7 @@ static int invoke_property_get(
break;
}
- return sd_bus_message_append_basic(m, v->x.property.signature[0], p);
+ return sd_bus_message_append_basic(reply, v->x.property.signature[0], p);
}
static int invoke_property_set(
@@ -367,8 +375,8 @@ static int invoke_property_set(
const char *interface,
const char *property,
sd_bus_message *value,
- sd_bus_error *error,
- void *userdata) {
+ void *userdata,
+ sd_bus_error *error) {
int r;
@@ -380,7 +388,7 @@ static int invoke_property_set(
assert(value);
if (v->x.property.set)
- return v->x.property.set(bus, path, interface, property, value, error, userdata);
+ return v->x.property.set(bus, path, interface, property, value, userdata, error);
/* Automatic handling if no callback is defined. */
@@ -428,8 +436,8 @@ static int property_get_set_callbacks_run(
bool is_get,
bool *found_object) {
- _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
void *u;
int r;
@@ -465,17 +473,11 @@ static int property_get_set_callbacks_run(
if (r < 0)
return r;
- r = invoke_property_get(bus, c->vtable, m->path, c->interface, c->member, reply, &error, u);
+ r = invoke_property_get(bus, c->vtable, m->path, c->interface, c->member, reply, u, &error);
if (r < 0)
- return r;
-
- if (sd_bus_error_is_set(&error)) {
- r = sd_bus_reply_method_error(m, &error);
- if (r < 0)
- return r;
-
- return 1;
- }
+ return sd_bus_reply_method_errno(m, r, &error);
+ if (sd_bus_error_is_set(&error))
+ return sd_bus_reply_method_error(m, &error);
if (bus->nodes_modified)
return 0;
@@ -486,33 +488,25 @@ static int property_get_set_callbacks_run(
} else {
if (c->vtable->type != _SD_BUS_VTABLE_WRITABLE_PROPERTY)
- sd_bus_error_setf(&error, SD_BUS_ERROR_PROPERTY_READ_ONLY, "Property '%s' is not writable.", c->member);
- else {
- /* Avoid that we call the set routine more
- * than once if the processing of this message
- * got restarted because the node tree
- * changed. */
- if (c->last_iteration == bus->iteration_counter)
- return 0;
-
- c->last_iteration = bus->iteration_counter;
+ return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_PROPERTY_READ_ONLY, "Property '%s' is not writable.", c->member);
- r = sd_bus_message_enter_container(m, 'v', c->vtable->x.property.signature);
- if (r < 0)
- return r;
+ /* Avoid that we call the set routine more than once
+ * if the processing of this message got restarted
+ * because the node tree changed. */
+ if (c->last_iteration == bus->iteration_counter)
+ return 0;
- r = invoke_property_set(bus, c->vtable, m->path, c->interface, c->member, m, &error, u);
- if (r < 0)
- return r;
- }
+ c->last_iteration = bus->iteration_counter;
- if (sd_bus_error_is_set(&error)) {
- r = sd_bus_reply_method_error(m, &error);
- if (r < 0)
- return r;
+ r = sd_bus_message_enter_container(m, 'v', c->vtable->x.property.signature);
+ if (r < 0)
+ return r;
- return 1;
- }
+ r = invoke_property_set(bus, c->vtable, m->path, c->interface, c->member, m, u, &error);
+ if (r < 0)
+ return sd_bus_reply_method_errno(m, r, &error);
+ if (sd_bus_error_is_set(&error))
+ return sd_bus_reply_method_error(m, &error);
if (bus->nodes_modified)
return 0;
@@ -561,11 +555,13 @@ static int vtable_append_all_properties(
if (r < 0)
return r;
- r = invoke_property_get(bus, v, path, c->interface, v->x.property.member, reply, error, vtable_property_convert_userdata(v, userdata));
- if (r < 0)
- return r;
+ r = invoke_property_get(bus, v, path, c->interface, v->x.property.member, reply, vtable_property_convert_userdata(v, userdata), error);
if (sd_bus_error_is_set(error))
return 0;
+ if (r < 0) {
+ sd_bus_error_set_errno(error, r);
+ return 0;
+ }
if (bus->nodes_modified)
return 0;
@@ -1944,9 +1940,11 @@ static int emit_properties_changed_on_interface(
if (r < 0)
return r;
- r = invoke_property_get(bus, v->vtable, 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, vtable_property_convert_userdata(v->vtable, u), &error);
if (r < 0)
return r;
+ if (sd_bus_error_is_set(&error))
+ return sd_bus_error_get_errno(&error);
if (bus->nodes_modified)
return 0;
diff --git a/src/libsystemd-bus/bus-util.c b/src/libsystemd-bus/bus-util.c
index 65323d0081..4d73df5853 100644
--- a/src/libsystemd-bus/bus-util.c
+++ b/src/libsystemd-bus/bus-util.c
@@ -31,10 +31,10 @@
#include "sd-bus.h"
#include "bus-error.h"
#include "bus-message.h"
-
#include "bus-util.h"
+#include "bus-internal.h"
-static int quit_callback(sd_bus *bus, sd_bus_message *m, void *userdata) {
+static int quit_callback(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
sd_event *e = userdata;
assert(bus);
@@ -103,25 +103,6 @@ int bus_event_loop_with_idle(sd_event *e, sd_bus *bus, const char *name, usec_t
return 0;
}
-int bus_property_get_tristate(
- sd_bus *bus,
- const char *path,
- const char *interface,
- const char *property,
- sd_bus_message *reply,
- sd_bus_error *error,
- void *userdata) {
-
- int *tristate = userdata;
- int r;
-
- r = sd_bus_message_append(reply, "b", *tristate > 0);
- if (r < 0)
- return r;
-
- return 1;
-}
-
int bus_verify_polkit(
sd_bus *bus,
sd_bus_message *m,
@@ -203,11 +184,30 @@ typedef struct AsyncPolkitQuery {
sd_bus_message_handler_t callback;
void *userdata;
uint64_t serial;
+ Hashmap *registry;
} AsyncPolkitQuery;
-static int async_polkit_callback(sd_bus *bus, sd_bus_message *reply, void *userdata) {
- AsyncPolkitQuery *q = userdata;
+static void async_polkit_query_free(sd_bus *b, AsyncPolkitQuery *q) {
+
+ if (!q)
+ return;
+
+ if (q->serial > 0 && b)
+ sd_bus_call_async_cancel(b, q->serial);
+
+ if (q->registry && q->request)
+ hashmap_remove(q->registry, q->request);
+
+ sd_bus_message_unref(q->request);
+ sd_bus_message_unref(q->reply);
+
+ free(q);
+}
+
+static int async_polkit_callback(sd_bus *bus, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
+ _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
_cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+ AsyncPolkitQuery *q = userdata;
int r;
assert(bus);
@@ -217,30 +217,18 @@ static int async_polkit_callback(sd_bus *bus, sd_bus_message *reply, void *userd
q->reply = sd_bus_message_ref(reply);
q->serial = 0;
- m = sd_bus_message_ref(q->request);
-
- r = sd_bus_message_rewind(m, true);
- if (r < 0)
- return r;
-
- r = q->callback(bus, m, q->userdata);
- if (r < 0)
- return r;
-
- return 1;
-}
-
-static void async_polkit_query_free(sd_bus *b, AsyncPolkitQuery *q) {
+ r = sd_bus_message_rewind(q->request, true);
+ if (r < 0) {
+ r = sd_bus_reply_method_errno(q->request, r, NULL);
+ goto finish;
+ }
- if (!q)
- return;
+ r = q->callback(bus, q->request, q->userdata, &error_buffer);
+ r = bus_maybe_reply_error(q->request, r, &error_buffer);
- if (q->serial > 0 && b)
- sd_bus_call_async_cancel(b, q->serial);
-
- sd_bus_message_unref(q->request);
- sd_bus_message_unref(q->reply);
- free(q);
+finish:
+ async_polkit_query_free(bus, q);
+ return r;
}
#endif
@@ -269,7 +257,7 @@ int bus_verify_polkit_async(
assert(action);
#ifdef ENABLE_POLKIT
- q = hashmap_remove(*registry, m);
+ q = hashmap_get(*registry, m);
if (q) {
int authorized, challenge;
@@ -281,26 +269,21 @@ int bus_verify_polkit_async(
if (sd_bus_message_is_method_error(q->reply, NULL)) {
const sd_bus_error *e;
- /* Treat no PK available as access denied */
- if (sd_bus_message_is_method_error(q->reply, SD_BUS_ERROR_SERVICE_UNKNOWN)) {
- async_polkit_query_free(bus, q);
- return -EACCES;
- }
-
+ /* Copy error from polkit reply */
e = sd_bus_message_get_error(q->reply);
sd_bus_error_copy(error, e);
- r = sd_bus_error_get_errno(e);
- async_polkit_query_free(bus, q);
- return r;
+ /* Treat no PK available as access denied */
+ if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN))
+ return -EACCES;
+
+ return sd_bus_error_get_errno(e);
}
r = sd_bus_message_enter_container(q->reply, 'r', "bba{ss}");
if (r >= 0)
r = sd_bus_message_read(q->reply, "bb", &authorized, &challenge);
- async_polkit_query_free(bus, q);
-
if (r < 0)
return r;
@@ -344,7 +327,7 @@ int bus_verify_polkit_async(
action,
0,
interactive ? 1 : 0,
- "");
+ NULL);
if (r < 0)
return r;
@@ -362,9 +345,13 @@ int bus_verify_polkit_async(
return r;
}
+ q->registry = *registry;
+
r = sd_bus_call_async(bus, pk, async_polkit_callback, q, 0, &q->serial);
- if (r < 0)
+ if (r < 0) {
+ async_polkit_query_free(bus, q);
return r;
+ }
return 0;
#endif
@@ -1000,14 +987,28 @@ int bus_open_transport_systemd(BusTransport transport, const char *host, bool us
return r;
}
+int bus_property_get_tristate(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+ int *tristate = userdata;
+
+ return sd_bus_message_append(reply, "b", *tristate > 0);
+}
+
int bus_property_get_bool(
sd_bus *bus,
const char *path,
const char *interface,
const char *property,
sd_bus_message *reply,
- sd_bus_error *error,
- void *userdata) {
+ void *userdata,
+ sd_bus_error *error) {
int b = *(bool*) userdata;
@@ -1021,8 +1022,8 @@ int bus_property_get_size(
const char *interface,
const char *property,
sd_bus_message *reply,
- sd_bus_error *error,
- void *userdata) {
+ void *userdata,
+ sd_bus_error *error) {
uint64_t sz = *(size_t*) userdata;
@@ -1037,8 +1038,8 @@ int bus_property_get_long(
const char *interface,
const char *property,
sd_bus_message *reply,
- sd_bus_error *error,
- void *userdata) {
+ void *userdata,
+ sd_bus_error *error) {
int64_t l = *(long*) userdata;
@@ -1051,8 +1052,8 @@ int bus_property_get_ulong(
const char *interface,
const char *property,
sd_bus_message *reply,
- sd_bus_error *error,
- void *userdata) {
+ void *userdata,
+ sd_bus_error *error) {
uint64_t ul = *(unsigned long*) userdata;
@@ -1088,3 +1089,29 @@ int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u) {
&u->job_type,
&u->job_path);
}
+
+int bus_maybe_reply_error(sd_bus_message *m, int r, sd_bus_error *error) {
+ assert(m);
+
+ if (r < 0) {
+ if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
+ sd_bus_reply_method_errno(m, r, error);
+
+ } else if (sd_bus_error_is_set(error)) {
+ if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
+ sd_bus_reply_method_error(m, error);
+
+ } else
+ return r;
+
+ log_debug("Failed to process message [type=%s sender=%s path=%s interface=%s member=%s signature=%s]: %s",
+ bus_message_type_to_string(m->header->type),
+ strna(m->sender),
+ strna(m->path),
+ strna(m->interface),
+ strna(m->member),
+ strna(m->root_container.signature),
+ bus_error_message(error, r));
+
+ return 1;
+}
diff --git a/src/libsystemd-bus/bus-util.h b/src/libsystemd-bus/bus-util.h
index c8d5dd982e..38533be66d 100644
--- a/src/libsystemd-bus/bus-util.h
+++ b/src/libsystemd-bus/bus-util.h
@@ -72,8 +72,8 @@ int bus_open_transport_systemd(BusTransport transport, const char *host, bool us
int bus_print_property(const char *name, sd_bus_message *property, bool all);
int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, char **filter, bool all);
-int bus_property_get_tristate(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, sd_bus_error *error, void *userdata);
-int bus_property_get_bool(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, sd_bus_error *error, void *userdata);
+int bus_property_get_tristate(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
+int bus_property_get_bool(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
#define bus_property_get_usec ((sd_bus_property_get_t) NULL)
#define bus_property_set_usec ((sd_bus_property_set_t) NULL)
@@ -89,15 +89,15 @@ assert_cc(sizeof(unsigned) == sizeof(unsigned));
#if __SIZEOF_SIZE_T__ == 8
#define bus_property_get_size ((sd_bus_property_get_t) NULL)
#else
-int bus_property_get_size(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, sd_bus_error *error, void *userdata);
+int bus_property_get_size(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
#endif
#if __SIZEOF_LONG__ == 8
#define bus_property_get_long ((sd_bus_property_get_t) NULL)
#define bus_property_get_ulong ((sd_bus_property_get_t) NULL)
#else
-int bus_property_get_long(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, sd_bus_error *error, void *userdata);
-int bus_property_get_ulong(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, sd_bus_error *error, void *userdata);
+int bus_property_get_long(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
+int bus_property_get_ulong(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
#endif
/* uid_t and friends on Linux 32 bit. This means we can just use the
@@ -146,8 +146,8 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_message*, sd_bus_message_unref);
const char *interface, \
const char *property, \
sd_bus_message *reply, \
- sd_bus_error *error, \
- void *userdata) { \
+ void *userdata, \
+ sd_bus_error *error) { \
\
const char *value; \
type *field = userdata; \
@@ -170,3 +170,5 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_message*, sd_bus_message_unref);
#define BUS_PROPERTY_DUAL_TIMESTAMP(name, offset, flags) \
SD_BUS_PROPERTY(name, "t", bus_property_get_usec, offset + offsetof(struct dual_timestamp, realtime), flags), \
SD_BUS_PROPERTY(name "Monotonic", "t", bus_property_get_usec, offset + offsetof(struct dual_timestamp, monotonic), flags)
+
+int bus_maybe_reply_error(sd_bus_message *m, int r, sd_bus_error *error);
diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c
index 7f00eee6e1..2604434467 100644
--- a/src/libsystemd-bus/sd-bus.c
+++ b/src/libsystemd-bus/sd-bus.c
@@ -365,7 +365,7 @@ _public_ int sd_bus_set_anonymous(sd_bus *bus, int b) {
return 0;
}
-static int hello_callback(sd_bus *bus, sd_bus_message *reply, void *userdata) {
+static int hello_callback(sd_bus *bus, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
const char *s;
int r;
@@ -1824,6 +1824,7 @@ _public_ int sd_bus_get_timeout(sd_bus *bus, uint64_t *timeout_usec) {
}
static int process_timeout(sd_bus *bus) {
+ _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
_cleanup_bus_message_unref_ sd_bus_message* m = NULL;
struct reply_callback *c;
usec_t n;
@@ -1857,12 +1858,13 @@ static int process_timeout(sd_bus *bus) {
bus->current = m;
bus->iteration_counter ++;
- r = c->callback(bus, m, c->userdata);
+ r = c->callback(bus, m, c->userdata, &error_buffer);
+ r = bus_maybe_reply_error(m, r, &error_buffer);
free(c);
bus->current = NULL;
- return r < 0 ? r : 1;
+ return r;
}
static int process_hello(sd_bus *bus, sd_bus_message *m) {
@@ -1888,6 +1890,7 @@ static int process_hello(sd_bus *bus, sd_bus_message *m) {
}
static int process_reply(sd_bus *bus, sd_bus_message *m) {
+ _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
struct reply_callback *c;
int r;
@@ -1909,13 +1912,15 @@ static int process_reply(sd_bus *bus, sd_bus_message *m) {
if (r < 0)
return r;
- r = c->callback(bus, m, c->userdata);
+ r = c->callback(bus, m, c->userdata, &error_buffer);
+ r = bus_maybe_reply_error(m, r, &error_buffer);
free(c);
- return r < 0 ? r : 1;
+ return r;
}
static int process_filter(sd_bus *bus, sd_bus_message *m) {
+ _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
struct filter_callback *l;
int r;
@@ -1940,7 +1945,8 @@ static int process_filter(sd_bus *bus, sd_bus_message *m) {
if (r < 0)
return r;
- r = l->callback(bus, m, l->userdata);
+ r = l->callback(bus, m, &error_buffer, l->userdata);
+ r = bus_maybe_reply_error(m, r, &error_buffer);
if (r != 0)
return r;
@@ -2123,6 +2129,8 @@ static int process_closing(sd_bus *bus, sd_bus_message **ret) {
c = hashmap_first(bus->reply_callbacks);
if (c) {
+ _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
+
/* First, fail all outstanding method calls */
r = bus_message_new_synthetic_error(
bus,
@@ -2144,12 +2152,10 @@ static int process_closing(sd_bus *bus, sd_bus_message **ret) {
bus->current = m;
bus->iteration_counter++;
- r = c->callback(bus, m, c->userdata);
+ r = c->callback(bus, m, c->userdata, &error_buffer);
+ r = bus_maybe_reply_error(m, r, &error_buffer);
free(c);
- if (r >= 0)
- r = 1;
-
goto finish;
}
diff --git a/src/libsystemd-bus/test-bus-chat.c b/src/libsystemd-bus/test-bus-chat.c
index 0c66dc794a..66a5df9b57 100644
--- a/src/libsystemd-bus/test-bus-chat.c
+++ b/src/libsystemd-bus/test-bus-chat.c
@@ -36,12 +36,12 @@
#include "bus-internal.h"
#include "bus-util.h"
-static int match_callback(sd_bus *bus, sd_bus_message *m, void *userdata) {
+static int match_callback(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
log_info("Match triggered! interface=%s member=%s", strna(sd_bus_message_get_interface(m)), strna(sd_bus_message_get_member(m)));
return 0;
}
-static int object_callback(sd_bus *bus, sd_bus_message *m, void *userdata) {
+static int object_callback(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
int r;
assert(bus);
@@ -361,7 +361,7 @@ finish:
return INT_TO_PTR(r);
}
-static int quit_callback(sd_bus *b, sd_bus_message *m, void *userdata) {
+static int quit_callback(sd_bus *b, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
bool *x = userdata;
log_error("Quit callback: %s", strerror(sd_bus_message_get_errno(m)));
diff --git a/src/libsystemd-bus/test-bus-introspect.c b/src/libsystemd-bus/test-bus-introspect.c
index b9865349ac..50c4c2d871 100644
--- a/src/libsystemd-bus/test-bus-introspect.c
+++ b/src/libsystemd-bus/test-bus-introspect.c
@@ -23,11 +23,11 @@
#include "log.h"
#include "bus-introspect.h"
-static int prop_get(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, sd_bus_error *error, void *userdata) {
+static int prop_get(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
return -EINVAL;
}
-static int prop_set(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, sd_bus_error *error, void *userdata) {
+static int prop_set(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
return -EINVAL;
}
diff --git a/src/libsystemd-bus/test-bus-match.c b/src/libsystemd-bus/test-bus-match.c
index 7d7c55247f..af42f0baa7 100644
--- a/src/libsystemd-bus/test-bus-match.c
+++ b/src/libsystemd-bus/test-bus-match.c
@@ -31,7 +31,7 @@
static bool mask[32];
-static int filter(sd_bus *b, sd_bus_message *m, void *userdata) {
+static int filter(sd_bus *b, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
log_info("Ran %i", PTR_TO_INT(userdata));
mask[PTR_TO_INT(userdata)] = true;
return 0;
diff --git a/src/libsystemd-bus/test-bus-objects.c b/src/libsystemd-bus/test-bus-objects.c
index 0e9ef57da1..043aa90b3c 100644
--- a/src/libsystemd-bus/test-bus-objects.c
+++ b/src/libsystemd-bus/test-bus-objects.c
@@ -44,7 +44,7 @@ struct context {
uint32_t automatic_integer_property;
};
-static int something_handler(sd_bus *bus, sd_bus_message *m, void *userdata) {
+static int something_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
struct context *c = userdata;
const char *s;
char *n = NULL;
@@ -67,7 +67,7 @@ static int something_handler(sd_bus *bus, sd_bus_message *m, void *userdata) {
return 1;
}
-static int exit_handler(sd_bus *bus, sd_bus_message *m, void *userdata) {
+static int exit_handler(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
struct context *c = userdata;
int r;
@@ -81,11 +81,11 @@ static int exit_handler(sd_bus *bus, sd_bus_message *m, void *userdata) {
return 1;
}
-static int get_handler(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, sd_bus_error *error, void *userdata) {
+static int get_handler(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
struct context *c = userdata;
int r;
- log_info("property get for %s called", property);
+ log_info("property get for %s called, returning \"%s\".", property, c->something);
r = sd_bus_message_append(reply, "s", c->something);
assert_se(r >= 0);
@@ -93,7 +93,7 @@ static int get_handler(sd_bus *bus, const char *path, const char *interface, con
return 1;
}
-static int set_handler(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *value, sd_bus_error *error, void *userdata) {
+static int set_handler(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *value, void *userdata, sd_bus_error *error) {
struct context *c = userdata;
const char *s;
char *n;
@@ -113,7 +113,7 @@ static int set_handler(sd_bus *bus, const char *path, const char *interface, con
return 1;
}
-static int value_handler(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, sd_bus_error *error, void *userdata) {
+static int value_handler(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
_cleanup_free_ char *s = NULL;
const char *x;
int r;
@@ -129,7 +129,7 @@ static int value_handler(sd_bus *bus, const char *path, const char *interface, c
return 1;
}
-static int notify_test(sd_bus *bus, sd_bus_message *m, void *userdata) {
+static int notify_test(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
int r;
assert_se(sd_bus_emit_properties_changed(bus, m->path, "org.freedesktop.systemd.ValueTest", "Value", NULL) >= 0);
@@ -140,7 +140,7 @@ static int notify_test(sd_bus *bus, sd_bus_message *m, void *userdata) {
return 1;
}
-static int emit_interfaces_added(sd_bus *bus, sd_bus_message *m, void *userdata) {
+static int emit_interfaces_added(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
int r;
assert_se(sd_bus_emit_interfaces_added(bus, m->path, "org.freedesktop.systemd.test", NULL) >= 0);
@@ -151,7 +151,7 @@ static int emit_interfaces_added(sd_bus *bus, sd_bus_message *m, void *userdata)
return 1;
}
-static int emit_interfaces_removed(sd_bus *bus, sd_bus_message *m, void *userdata) {
+static int emit_interfaces_removed(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
int r;
assert_se(sd_bus_emit_interfaces_removed(bus, m->path, "org.freedesktop.systemd.test", NULL) >= 0);
@@ -435,7 +435,7 @@ static int client(struct context *c) {
}
int main(int argc, char *argv[]) {
- struct context c;
+ struct context c = {};
pthread_t s;
void *p;
int r, q;