From: Zbigniew Jędrzejewski-Szmek Date: Wed, 15 Apr 2020 15:21:23 +0000 (+0200) Subject: sd-bus: add helper struct for interface definitions X-Git-Tag: v246-rc1~433^2~22 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6a7e98aacada79e273ddcad7335a7be7c2add801;p=thirdparty%2Fsystemd.git sd-bus: add helper struct for interface definitions The idea is to have a static table that defines the dbus API. The vtable is defined right next to the interface name and path because they are logically connected. --- diff --git a/src/shared/bus-log-control-api.c b/src/shared/bus-log-control-api.c index ffc52c77745..a1d0d172915 100644 --- a/src/shared/bus-log-control-api.c +++ b/src/shared/bus-log-control-api.c @@ -107,17 +107,8 @@ static const sd_bus_vtable log_control_vtable[] = { SD_BUS_VTABLE_END, }; -int bus_log_control_api_register(sd_bus *bus) { - int r; - - r = sd_bus_add_object_vtable( - bus, - NULL, - "/org/freedesktop/LogControl1", - "org.freedesktop.LogControl1", - log_control_vtable, NULL); - if (r < 0) - return log_error_errno(r, "Failed to register service API object: %m"); - - return 0; -} +const BusObjectImplementation log_control_object = { + "/org/freedesktop/LogControl1", + "org.freedesktop.LogControl1", + .vtables = BUS_VTABLES(log_control_vtable), +}; diff --git a/src/shared/bus-log-control-api.h b/src/shared/bus-log-control-api.h index a6fb2757c5f..b1d00b38bcf 100644 --- a/src/shared/bus-log-control-api.h +++ b/src/shared/bus-log-control-api.h @@ -2,7 +2,12 @@ #include "sd-bus.h" -int bus_log_control_api_register(sd_bus *bus); +#include "bus-util.h" + +extern const BusObjectImplementation log_control_object; +static inline int bus_log_control_api_register(sd_bus *bus) { + return bus_add_implementation(bus, &log_control_object, NULL); +} int bus_property_get_log_level(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error); int bus_property_set_log_level(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *value, void *userdata, sd_bus_error *error); diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c index 81683e5afed..30d62d5fc77 100644 --- a/src/shared/bus-util.c +++ b/src/shared/bus-util.c @@ -1549,3 +1549,52 @@ int bus_message_new_method_call( return sd_bus_message_new_method_call(bus, m, locator->destination, locator->path, locator->interface, member); } + +int bus_add_implementation(sd_bus *bus, const BusObjectImplementation *impl, void *userdata) { + int r; + + log_debug("Registering bus object implementation for path=%s iface=%s", impl->path, impl->interface); + + for (const sd_bus_vtable **p = impl->vtables; p && *p; p++) { + r = sd_bus_add_object_vtable(bus, NULL, + impl->path, + impl->interface, + *p, + userdata); + if (r < 0) + return log_error_errno(r, "Failed to register bus path %s with interface %s: %m", + impl->path, + impl->interface); + } + + for (const BusObjectVtablePair *p = impl->fallback_vtables; p && p->vtable; p++) { + r = sd_bus_add_fallback_vtable(bus, NULL, + impl->path, + impl->interface, + p->vtable, + p->object_find, + userdata); + if (r < 0) + return log_error_errno(r, "Failed to register bus path %s with interface %s: %m", + impl->path, + impl->interface); + } + + if (impl->node_enumerator) { + r = sd_bus_add_node_enumerator(bus, NULL, + impl->path, + impl->node_enumerator, + userdata); + if (r < 0) + return log_error_errno(r, "Failed to add node enumerator for %s: %m", + impl->path); + } + + for (size_t i = 0; impl->children && impl->children[i]; i++) { + r = bus_add_implementation(bus, impl->children[i], userdata); + if (r < 0) + return r; + } + + return 0; +} diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h index fd1820ca7e6..a985523cd01 100644 --- a/src/shared/bus-util.h +++ b/src/shared/bus-util.h @@ -23,11 +23,32 @@ typedef enum BusTransport { } BusTransport; typedef struct BusLocator { - const char *destination; - const char *path; - const char *interface; + const char *destination; + const char *path; + const char *interface; } BusLocator; +typedef struct BusObjectImplementation BusObjectImplementation; + +typedef struct BusObjectVtablePair { + const sd_bus_vtable *vtable; + sd_bus_object_find_t object_find; +} BusObjectVtablePair; + +struct BusObjectImplementation { + const char *path; + const char *interface; + const sd_bus_vtable **vtables; + const BusObjectVtablePair *fallback_vtables; + sd_bus_node_enumerator_t node_enumerator; + bool manager; + const BusObjectImplementation **children; +}; + +#define BUS_VTABLES(...) ((const sd_bus_vtable* []){ __VA_ARGS__, NULL }) +#define BUS_FALLBACK_VTABLES(...) ((const BusObjectVtablePair[]) { __VA_ARGS__, {} }) +#define BUS_IMPLEMENTATIONS(...) ((const BusObjectImplementation* []) { __VA_ARGS__, NULL }) + typedef int (*bus_property_set_t) (sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata); struct bus_properties_map { @@ -199,3 +220,5 @@ int bus_set_property(sd_bus *bus, const BusLocator *locator, const char *member, int bus_match_signal(sd_bus *bus, sd_bus_slot **ret, const BusLocator *locator, const char *member, sd_bus_message_handler_t callback, void *userdata); int bus_match_signal_async(sd_bus *bus, sd_bus_slot **ret, const BusLocator *locator, const char *member, sd_bus_message_handler_t callback, sd_bus_message_handler_t install_callback, void *userdata); int bus_message_new_method_call(sd_bus *bus, sd_bus_message **m, const BusLocator *locator, const char *member); + +int bus_add_implementation(sd_bus *bus, const BusObjectImplementation *impl, void *userdata);