]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-bus: split introspection into the content creation and reply creation parts
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 19 Apr 2019 10:14:35 +0000 (12:14 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 23 Apr 2019 10:23:15 +0000 (12:23 +0200)
Just moving code around, in preparation to allow the content creation
part to be used in other places.

On the surface of things, introspect_path() should be in bus-introspect.c, but
introspect_path() uses many static helper functions in bus-objects.c, so moving
it would require all of them to be exposed, which is too much trouble.

test-bus-introspect is updated to actually write the closing bracket.

src/libsystemd/sd-bus/bus-introspect.c
src/libsystemd/sd-bus/bus-introspect.h
src/libsystemd/sd-bus/bus-objects.c
src/libsystemd/sd-bus/bus-objects.h
src/libsystemd/sd-bus/test-bus-introspect.c

index 022eddb10f66a1e90675b6c5b84fafb78dd34e79..beab80687d6f1a6e370f3ee2009d6d3924cbee34 100644 (file)
@@ -172,13 +172,10 @@ int introspect_write_interface(struct introspect *i, const sd_bus_vtable *v) {
         return 0;
 }
 
-int introspect_finish(struct introspect *i, sd_bus *bus, sd_bus_message *m, sd_bus_message **reply) {
-        sd_bus_message *q;
+int introspect_finish(struct introspect *i, char **ret) {
         int r;
 
         assert(i);
-        assert(m);
-        assert(reply);
 
         fputs("</node>\n", i->f);
 
@@ -186,25 +183,17 @@ int introspect_finish(struct introspect *i, sd_bus *bus, sd_bus_message *m, sd_b
         if (r < 0)
                 return r;
 
-        r = sd_bus_message_new_method_return(m, &q);
-        if (r < 0)
-                return r;
-
-        r = sd_bus_message_append(q, "s", i->introspection);
-        if (r < 0) {
-                sd_bus_message_unref(q);
-                return r;
-        }
+        i->f = safe_fclose(i->f);
+        *ret = TAKE_PTR(i->introspection);
 
-        *reply = q;
         return 0;
 }
 
 void introspect_free(struct introspect *i) {
         assert(i);
 
-        safe_fclose(i->f);
+        /* Normally introspect_finish() does all the work, this is just a backup for error paths */
 
+        safe_fclose(i->f);
         free(i->introspection);
-        zero(*i);
 }
index bb2dd7ef7b9a1d11f30870f6a8751929acce1d43..ccbb543d0c9d491133fae5327885ba4a2d950365 100644 (file)
@@ -18,5 +18,5 @@ int introspect_begin(struct introspect *i, bool trusted);
 int introspect_write_default_interfaces(struct introspect *i, bool object_manager);
 int introspect_write_child_nodes(struct introspect *i, Set *s, const char *prefix);
 int introspect_write_interface(struct introspect *i, const sd_bus_vtable *v);
-int introspect_finish(struct introspect *i, sd_bus *bus, sd_bus_message *m, sd_bus_message **reply);
+int introspect_finish(struct introspect *i, char **ret);
 void introspect_free(struct introspect *i);
index 650cee63afdfbcebad2ecd9bf9fe603cb8d9d0b7..22db75479ce8b122f593ad3a2586ce51c539cf75 100644 (file)
@@ -883,15 +883,15 @@ static int bus_node_exists(
         return 0;
 }
 
-static int process_introspect(
+int introspect_path(
                 sd_bus *bus,
-                sd_bus_message *m,
+                const char *path,
                 struct node *n,
                 bool require_fallback,
-                bool *found_object) {
+                bool *found_object,
+                char **ret,
+                sd_bus_error *error) {
 
-        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
-        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
         _cleanup_set_free_free_ Set *s = NULL;
         const char *previous_interface = NULL;
         _cleanup_(introspect_free) struct introspect intro = {};
@@ -899,14 +899,9 @@ static int process_introspect(
         bool empty;
         int r;
 
-        assert(bus);
-        assert(m);
-        assert(n);
-        assert(found_object);
-
-        r = get_child_nodes(bus, m->path, n, 0, &s, &error);
+        r = get_child_nodes(bus, path, n, 0, &s, error);
         if (r < 0)
-                return bus_maybe_reply_error(m, r, &error);
+                return r;
         if (bus->nodes_modified)
                 return 0;
 
@@ -924,9 +919,9 @@ static int process_introspect(
                 if (require_fallback && !c->is_fallback)
                         continue;
 
-                r = node_vtable_get_userdata(bus, m->path, c, NULL, &error);
+                r = node_vtable_get_userdata(bus, path, c, NULL, error);
                 if (r < 0)
-                        return bus_maybe_reply_error(m, r, &error);
+                        return r;
                 if (bus->nodes_modified)
                         return 0;
                 if (r == 0)
@@ -957,20 +952,55 @@ static int process_introspect(
         if (empty) {
                 /* Nothing?, let's see if we exist at all, and if not
                  * refuse to do anything */
-                r = bus_node_exists(bus, n, m->path, require_fallback);
+                r = bus_node_exists(bus, n, path, require_fallback);
                 if (r <= 0)
-                        return bus_maybe_reply_error(m, r, &error);
+                        return r;
                 if (bus->nodes_modified)
                         return 0;
         }
 
         *found_object = true;
 
-        r = introspect_write_child_nodes(&intro, s, m->path);
+        r = introspect_write_child_nodes(&intro, s, path);
+        if (r < 0)
+                return r;
+
+        r = introspect_finish(&intro, ret);
+        if (r < 0)
+                return r;
+
+        return 1;
+}
+
+static int process_introspect(
+                sd_bus *bus,
+                sd_bus_message *m,
+                struct node *n,
+                bool require_fallback,
+                bool *found_object) {
+
+        _cleanup_free_ char *s = NULL;
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+        int r;
+
+        assert(bus);
+        assert(m);
+        assert(n);
+        assert(found_object);
+
+        r = introspect_path(bus, m->path, n, require_fallback, found_object, &s, &error);
+        if (r < 0)
+                return bus_maybe_reply_error(m, r, &error);
+        if (r == 0)
+                /* nodes_modified == true */
+                return 0;
+
+        r = sd_bus_message_new_method_return(m, &reply);
         if (r < 0)
                 return r;
 
-        r = introspect_finish(&intro, bus, m, &reply);
+        r = sd_bus_message_append(reply, "s", s);
         if (r < 0)
                 return r;
 
index b45fe6323efc08e66472ee7417ac91b9a8d5c5d2..7f38853da1c3998f97024472059efab7afee8a37 100644 (file)
@@ -2,8 +2,18 @@
 #pragma once
 
 #include "bus-internal.h"
+#include "bus-introspect.h"
 
 const sd_bus_vtable* bus_vtable_next(const sd_bus_vtable *vtable, const sd_bus_vtable *v);
 bool bus_vtable_has_names(const sd_bus_vtable *vtable);
 int bus_process_object(sd_bus *bus, sd_bus_message *m);
 void bus_node_gc(sd_bus *b, struct node *n);
+
+int introspect_path(
+                sd_bus *bus,
+                const char *path,
+                struct node *n,
+                bool require_fallback,
+                bool *found_object,
+                char **ret,
+                sd_bus_error *error);
index 968de40e5a7108ac1346e8378afcaa7f24e0e4da..797b19f9f18e94279b21f5b6512ffa3a1ce3550e 100644 (file)
@@ -27,10 +27,9 @@ static const sd_bus_vtable vtable[] = {
         SD_BUS_VTABLE_END
 };
 
-int main(int argc, char *argv[]) {
-        _cleanup_(introspect_free) struct introspect intro = {};
-
-        test_setup_logging(LOG_DEBUG);
+static void test_manual_introspection(void) {
+        struct introspect intro = {};
+        _cleanup_free_ char *s = NULL;
 
         assert_se(introspect_begin(&intro, false) >= 0);
 
@@ -38,8 +37,14 @@ int main(int argc, char *argv[]) {
         assert_se(introspect_write_interface(&intro, vtable) >= 0);
         fputs(" </interface>\n", intro.f);
 
-        fflush(intro.f);
-        fputs(intro.introspection, stdout);
+        assert_se(introspect_finish(&intro, &s) == 0);
+        fputs(s, stdout);
+}
+
+int main(int argc, char *argv[]) {
+        test_setup_logging(LOG_DEBUG);
+
+        test_manual_introspection();
 
         return 0;
 }