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.
This commit is contained in:
parent
2abda6d1e4
commit
dff9e25a76
|
@ -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;
|
||||
i->f = safe_fclose(i->f);
|
||||
*ret = TAKE_PTR(i->introspection);
|
||||
|
||||
r = sd_bus_message_append(q, "s", i->introspection);
|
||||
if (r < 0) {
|
||||
sd_bus_message_unref(q);
|
||||
return r;
|
||||
}
|
||||
|
||||
*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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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, bus, m, &reply);
|
||||
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 = sd_bus_message_append(reply, "s", s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue