From 621b3d0862aa95d17c11b86217c87b3c41aea862 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanislav=20Angelovi=C4=8D?= Date: Mon, 9 Oct 2023 15:46:39 +0200 Subject: [PATCH] feat: enable creation of IConnection from sd_bus object (#363) --- include/sdbus-c++/IConnection.h | 31 +++++++++++++++++++++++++++++++ src/Connection.cpp | 13 +++++++++++++ src/Connection.h | 3 +++ 3 files changed, 47 insertions(+) diff --git a/include/sdbus-c++/IConnection.h b/include/sdbus-c++/IConnection.h index f698918..e82ce00 100644 --- a/include/sdbus-c++/IConnection.h +++ b/include/sdbus-c++/IConnection.h @@ -34,6 +34,8 @@ #include #include +struct sd_bus; + namespace sdbus { /********************************************//** @@ -497,6 +499,35 @@ namespace sdbus { * @throws sdbus::Error in case of failure */ [[nodiscard]] std::unique_ptr createServerBus(int fd); + + /*! + * @brief Creates sdbus-c++ bus connection representation out of underlying sd_bus instance + * + * @param[in] bus File descriptor to use for server DBus connection + * @return Connection instance + * + * This functions is helpful in cases where clients need a custom, tweaked configuration of their + * bus object. Since sdbus-c++ does not provide C++ API for all bus connection configuration + * functions of the underlying sd-bus library, clients can use these sd-bus functions themselves + * to create and configure their sd_bus object, and create sdbus-c++ IConnection on top of it. + * + * The IConnection instance assumes unique ownership of the provided bus object. The bus object + * must have been started by the client before this call. + * The bus object will get flushed, closed, and unreffed when the IConnection instance is destroyed. + * + * @throws sdbus::Error in case of failure + * + * Code example: + * @code + * sd_bus* bus{}; + * ::sd_bus_new(&bus); + * ::sd_bus_set_address(bus, address); + * ::sd_bus_set_anonymous(bus, true); + * ::sd_bus_start(bus); + * auto con = sdbus::createBusConnection(bus); // IConnection consumes sd_bus object + * @endcode + */ + [[nodiscard]] std::unique_ptr createBusConnection(sd_bus *bus); } #endif /* SDBUS_CXX_ICONNECTION_H_ */ diff --git a/src/Connection.cpp b/src/Connection.cpp index 27fd445..ee02deb 100644 --- a/src/Connection.cpp +++ b/src/Connection.cpp @@ -85,6 +85,11 @@ Connection::Connection(std::unique_ptr&& interface, server_bus_t, int fd { } +Connection::Connection(std::unique_ptr&& interface, sdbus_bus_t, sd_bus *bus) + : Connection(std::move(interface), [&](sd_bus** b) { *b = bus; return 0; }) +{ +} + Connection::Connection(std::unique_ptr&& interface, pseudo_bus_t) : iface_(std::move(interface)) , bus_(openPseudoBus()) @@ -704,4 +709,12 @@ std::unique_ptr createServerBus(int fd) return std::make_unique(std::move(interface), Connection::server_bus, fd); } +std::unique_ptr createBusConnection(sd_bus *bus) +{ + SDBUS_THROW_ERROR_IF(bus == nullptr, "Invalid bus argument", EINVAL); + + auto interface = std::make_unique(); + return std::make_unique(std::move(interface), Connection::sdbus_bus, bus); +} + } // namespace sdbus diff --git a/src/Connection.h b/src/Connection.h index 6de5474..a0a320b 100644 --- a/src/Connection.h +++ b/src/Connection.h @@ -61,6 +61,8 @@ namespace sdbus::internal { inline static constexpr private_bus_t private_bus{}; struct server_bus_t{}; inline static constexpr server_bus_t server_bus{}; + struct sdbus_bus_t{}; // A bus connection created directly from existing sd_bus instance + inline static constexpr sdbus_bus_t sdbus_bus{}; struct pseudo_bus_t{}; // A bus connection that is not really established with D-Bus daemon inline static constexpr pseudo_bus_t pseudo_bus{}; @@ -72,6 +74,7 @@ namespace sdbus::internal { Connection(std::unique_ptr&& interface, private_bus_t, const std::string& address); Connection(std::unique_ptr&& interface, private_bus_t, int fd); Connection(std::unique_ptr&& interface, server_bus_t, int fd); + Connection(std::unique_ptr&& interface, sdbus_bus_t, sd_bus *bus); Connection(std::unique_ptr&& interface, pseudo_bus_t); ~Connection() override;