summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2019-04-19 12:14:35 +0200
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2019-04-23 12:23:15 +0200
commitdff9e25a76debcc63a70c9d02bcf77485da6b305 (patch)
tree0e5ba2848240767bd208a1521dbda3e6bdee60ee
parent2abda6d1e4a4f18a6033f865cf83d914a3f27e9e (diff)
downloadsystemd-dff9e25a76debcc63a70c9d02bcf77485da6b305.tar.gz
sd-bus: split introspection into the content creation and reply creation parts
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.
-rw-r--r--src/libsystemd/sd-bus/bus-introspect.c21
-rw-r--r--src/libsystemd/sd-bus/bus-introspect.h2
-rw-r--r--src/libsystemd/sd-bus/bus-objects.c66
-rw-r--r--src/libsystemd/sd-bus/bus-objects.h10
-rw-r--r--src/libsystemd/sd-bus/test-bus-introspect.c17
5 files changed, 75 insertions, 41 deletions
diff --git a/src/libsystemd/sd-bus/bus-introspect.c b/src/libsystemd/sd-bus/bus-introspect.c
index 022eddb10f..beab80687d 100644
--- a/src/libsystemd/sd-bus/bus-introspect.c
+++ b/src/libsystemd/sd-bus/bus-introspect.c
@@ -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);
}
diff --git a/src/libsystemd/sd-bus/bus-introspect.h b/src/libsystemd/sd-bus/bus-introspect.h
index bb2dd7ef7b..ccbb543d0c 100644
--- a/src/libsystemd/sd-bus/bus-introspect.h
+++ b/src/libsystemd/sd-bus/bus-introspect.h
@@ -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);
diff --git a/src/libsystemd/sd-bus/bus-objects.c b/src/libsystemd/sd-bus/bus-objects.c
index 650cee63af..22db75479c 100644
--- a/src/libsystemd/sd-bus/bus-objects.c
+++ b/src/libsystemd/sd-bus/bus-objects.c
@@ -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;
diff --git a/src/libsystemd/sd-bus/bus-objects.h b/src/libsystemd/sd-bus/bus-objects.h
index b45fe6323e..7f38853da1 100644
--- a/src/libsystemd/sd-bus/bus-objects.h
+++ b/src/libsystemd/sd-bus/bus-objects.h
@@ -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);
diff --git a/src/libsystemd/sd-bus/test-bus-introspect.c b/src/libsystemd/sd-bus/test-bus-introspect.c
index 968de40e5a..797b19f9f1 100644
--- a/src/libsystemd/sd-bus/test-bus-introspect.c
+++ b/src/libsystemd/sd-bus/test-bus-introspect.c
@@ -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;
}