chiark / gitweb /
bus: properly serialize unit file change list
[elogind.git] / src / libsystemd-bus / bus-objects.c
index a6e8b2de867a38d5ea1e4a67026585a08bd83676..06be5ed7d8ff9ea935fe22b3164f4d9a9621d51c 100644 (file)
@@ -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;
         }
@@ -289,21 +292,23 @@ static int method_callbacks_run(
                 return -EINVAL;
 
         if (!streq(strempty(c->vtable->x.method.signature), signature)) {
-                r = sd_bus_reply_method_errorf(bus, m,
-                                               SD_BUS_ERROR_INVALID_ARGS,
-                                               "Invalid arguments '%s' to call %s:%s, expecting '%s'.",
-                                               signature, c->interface, c->member, strempty(c->vtable->x.method.signature));
-                if (r < 0)
-                        return r;
-
-                return 1;
+                return sd_bus_reply_method_errorf(
+                                m,
+                                SD_BUS_ERROR_INVALID_ARGS,
+                                "Invalid arguments '%s' to call %s.%s(), expecting '%s'.",
+                                signature, c->interface, c->member, strempty(c->vtable->x.method.signature));
         }
 
-        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(bus, m, NULL);
+        r = sd_bus_reply_method_return(m, NULL);
         if (r < 0)
                 return r;
 
@@ -316,9 +321,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 +332,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 +362,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 +372,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 +385,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 +433,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;
 
@@ -449,7 +454,7 @@ static int property_get_set_callbacks_run(
 
         *found_object = true;
 
-        r = sd_bus_message_new_method_return(bus, m, &reply);
+        r = sd_bus_message_new_method_return(m, &reply);
         if (r < 0)
                 return r;
 
@@ -465,17 +470,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(bus, 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 +485,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;
+                        return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_PROPERTY_READ_ONLY, "Property '%s' is not writable.", c->member);
 
-                        c->last_iteration = bus->iteration_counter;
-
-                        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(bus, 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 +552,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;
 
@@ -598,7 +591,7 @@ static int property_get_all_callbacks_run(
         assert(m);
         assert(found_object);
 
-        r = sd_bus_message_new_method_return(bus, m, &reply);
+        r = sd_bus_message_new_method_return(m, &reply);
         if (r < 0)
                 return r;
 
@@ -637,7 +630,7 @@ static int property_get_all_callbacks_run(
                         return r;
 
                 if (sd_bus_error_is_set(&error)) {
-                        r = sd_bus_reply_method_error(bus, m, &error);
+                        r = sd_bus_reply_method_error(m, &error);
                         if (r < 0)
                                 return r;
 
@@ -649,7 +642,7 @@ static int property_get_all_callbacks_run(
 
         if (!found_interface) {
                 r = sd_bus_reply_method_errorf(
-                                bus, m,
+                                m,
                                 SD_BUS_ERROR_UNKNOWN_INTERFACE,
                                 "Unknown interface '%s'.", iface);
                 if (r < 0)
@@ -1004,7 +997,7 @@ static int process_get_managed_objects(
         if (bus->nodes_modified)
                 return 0;
 
-        r = sd_bus_message_new_method_return(bus, m, &reply);
+        r = sd_bus_message_new_method_return(m, &reply);
         if (r < 0)
                 return r;
 
@@ -1048,7 +1041,7 @@ static int process_get_managed_objects(
                                 return -ENOMEM;
 
                         if (sd_bus_error_is_set(&error)) {
-                                r = sd_bus_reply_method_error(bus, m, &error);
+                                r = sd_bus_reply_method_error(m, &error);
                                 if (r < 0)
                                         return r;
 
@@ -1232,12 +1225,12 @@ int bus_process_object(sd_bus *bus, sd_bus_message *m) {
         if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus.Properties", "Get") ||
             sd_bus_message_is_method_call(m, "org.freedesktop.DBus.Properties", "Set"))
                 r = sd_bus_reply_method_errorf(
-                                bus, m,
+                                m,
                                 SD_BUS_ERROR_UNKNOWN_PROPERTY,
                                 "Unknown property or interface.");
         else
                 r = sd_bus_reply_method_errorf(
-                                bus, m,
+                                m,
                                 SD_BUS_ERROR_UNKNOWN_METHOD,
                                 "Unknown method '%s' or interface '%s'.", m->member, m->interface);
 
@@ -1944,9 +1937,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;