diff --git a/src/libsystemd/sd-bus/bus-introspect.c b/src/libsystemd/sd-bus/bus-introspect.c index 07bd98967d..3e2bfc566b 100644 --- a/src/libsystemd/sd-bus/bus-introspect.c +++ b/src/libsystemd/sd-bus/bus-introspect.c @@ -40,12 +40,27 @@ int introspect_write_default_interfaces(struct introspect *i, bool object_manage return 0; } +static int set_interface_name(struct introspect *intro, const char *interface_name) { + if (streq_ptr(intro->interface_name, interface_name)) + return 0; + + if (intro->interface_name) + fputs(" \n", intro->f); + + if (interface_name) + fprintf(intro->f, " \n", interface_name); + + return free_and_strdup(&intro->interface_name, interface_name); +} + int introspect_write_child_nodes(struct introspect *i, Set *s, const char *prefix) { char *node; assert(i); assert(prefix); + assert_se(set_interface_name(i, NULL) >= 0); + while ((node = set_steal_first(s))) { const char *e; @@ -115,13 +130,23 @@ static int introspect_write_arguments(struct introspect *i, const char *signatur } } -int introspect_write_interface(struct introspect *i, const sd_bus_vtable *v) { +int introspect_write_interface( + struct introspect *i, + const char *interface_name, + const sd_bus_vtable *v) { + const sd_bus_vtable *vtable = v; const char *names = ""; + int r; assert(i); + assert(interface_name); assert(v); + r = set_interface_name(i, interface_name); + if (r < 0) + return r; + for (; v->type != _SD_BUS_VTABLE_END; v = bus_vtable_next(vtable, v)) { /* Ignore methods, signals and properties that are @@ -178,6 +203,8 @@ int introspect_finish(struct introspect *i, char **ret) { assert(i); + assert_se(set_interface_name(i, NULL) >= 0); + fputs("\n", i->f); r = fflush_and_check(i->f); @@ -196,5 +223,6 @@ void introspect_free(struct introspect *i) { /* Normally introspect_finish() does all the work, this is just a backup for error paths */ safe_fclose(i->f); + free(i->interface_name); free(i->introspection); } diff --git a/src/libsystemd/sd-bus/bus-introspect.h b/src/libsystemd/sd-bus/bus-introspect.h index ccbb543d0c..19d39923e5 100644 --- a/src/libsystemd/sd-bus/bus-introspect.h +++ b/src/libsystemd/sd-bus/bus-introspect.h @@ -9,6 +9,7 @@ struct introspect { FILE *f; + char *interface_name; char *introspection; size_t size; bool trusted; @@ -17,6 +18,9 @@ struct introspect { 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_write_interface( + struct introspect *i, + const char *interface_name, + const sd_bus_vtable *v); 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 913d6eca8a..eaf230709b 100644 --- a/src/libsystemd/sd-bus/bus-objects.c +++ b/src/libsystemd/sd-bus/bus-objects.c @@ -939,7 +939,6 @@ int introspect_path( sd_bus_error *error) { _cleanup_set_free_free_ Set *s = NULL; - const char *previous_interface = NULL; _cleanup_(introspect_free) struct introspect intro = {}; struct node_vtable *c; bool empty; @@ -984,23 +983,11 @@ int introspect_path( if (c->vtable[0].flags & SD_BUS_VTABLE_HIDDEN) continue; - if (!streq_ptr(previous_interface, c->interface)) { - if (previous_interface) - fputs(" \n", intro.f); - - fprintf(intro.f, " \n", c->interface); - } - - r = introspect_write_interface(&intro, c->vtable); + r = introspect_write_interface(&intro, c->interface, c->vtable); if (r < 0) return r; - - previous_interface = c->interface; } - if (previous_interface) - fputs(" \n", intro.f); - if (empty) { /* Nothing?, let's see if we exist at all, and if not * refuse to do anything */ diff --git a/src/libsystemd/sd-bus/test-bus-introspect.c b/src/libsystemd/sd-bus/test-bus-introspect.c index 9c8d1434b1..cbc3158924 100644 --- a/src/libsystemd/sd-bus/test-bus-introspect.c +++ b/src/libsystemd/sd-bus/test-bus-introspect.c @@ -14,11 +14,11 @@ static void test_manual_introspection(const sd_bus_vtable vtable[]) { assert_se(introspect_begin(&intro, false) >= 0); - fprintf(intro.f, " \n"); - assert_se(introspect_write_interface(&intro, vtable) >= 0); - fputs(" \n", intro.f); - + assert_se(introspect_write_interface(&intro, "org.foo", vtable) >= 0); + /* write again to check if output looks OK for a different interface */ + assert_se(introspect_write_interface(&intro, "org.foo.bar", vtable) >= 0); assert_se(introspect_finish(&intro, &s) == 0); + fputs(s, stdout); fputs("\n", stdout); }