diff options
-rw-r--r-- | src/libsystemd/sd-bus/bus-introspect.c | 21 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-introspect.h | 2 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-objects.c | 66 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-objects.h | 10 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/test-bus-introspect.c | 17 |
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; } |