table of contents
SD_BUS_ADD_OBJECT_VTABLE(3) | sd_bus_add_object_vtable | SD_BUS_ADD_OBJECT_VTABLE(3) |
NAME¶
sd_bus_add_object_vtable, sd_bus_add_fallback_vtable, SD_BUS_VTABLE_START, SD_BUS_VTABLE_END, SD_BUS_METHOD_WITH_NAMES_OFFSET, SD_BUS_METHOD_WITH_NAMES, SD_BUS_METHOD_WITH_OFFSET, SD_BUS_METHOD, SD_BUS_SIGNAL_WITH_NAMES, SD_BUS_SIGNAL, SD_BUS_WRITABLE_PROPERTY, SD_BUS_PROPERTY, SD_BUS_PARAM - Declare properties and methods for a D-Bus path
SYNOPSIS¶
#include <elogind/sd-bus-vtable.h>
typedef int (*sd_bus_message_handler_t)(sd_bus_message *m, void *userdata, sd_bus_error *ret_error);
typedef int (*sd_bus_property_get_t)(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *ret_error);
typedef int (*sd_bus_property_set_t)(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *value, void *userdata, sd_bus_error *ret_error);
typedef int (*sd_bus_object_find_t)(const char *path, const char *interface, void *userdata, void **ret_found, sd_bus_error *ret_error);
int sd_bus_add_object_vtable(sd_bus *bus, sd_bus_slot **slot, const char *path, const char *interface, const sd_bus_vtable *vtable, void *userdata);
int sd_bus_add_fallback_vtable(sd_bus *bus, sd_bus_slot **slot, const char *prefix, const char *interface, const sd_bus_vtable *vtable, sd_bus_object_find_t find, void *userdata);
SD_BUS_VTABLE_START(flags)
SD_BUS_VTABLE_END
SD_BUS_METHOD_WITH_NAMES_OFFSET( member, signature, in_names, result, out_names, handler, offset, flags)
SD_BUS_METHOD_WITH_NAMES( member, signature, in_names, result, out_names, handler, flags)
SD_BUS_METHOD_WITH_OFFSET( member, signature, result, handler, offset, flags)
SD_BUS_METHOD( member, signature, result, handler, flags)
SD_BUS_SIGNAL_WITH_NAMES( member, signature, names, flags)
SD_BUS_SIGNAL( member, signature, flags)
SD_BUS_WRITABLE_PROPERTY( member, signature, get, set, offset, flags)
SD_BUS_PROPERTY( member, signature, get, offset, flags)
SD_BUS_PARAM(name)
DESCRIPTION¶
sd_bus_add_object_vtable() is used to declare attributes for the path object path path connected to the bus connection bus under the interface interface. The table vtable may contain property declarations using SD_BUS_PROPERTY() or SD_BUS_WRITABLE_PROPERTY(), method declarations using SD_BUS_METHOD(), SD_BUS_METHOD_WITH_NAMES(), SD_BUS_METHOD_WITH_OFFSET(), or SD_BUS_METHOD_WITH_NAMES_OFFSET(), and signal declarations using SD_BUS_SIGNAL_WITH_NAMES() or SD_BUS_SIGNAL(), see below. The userdata parameter contains a pointer that will be passed to various callback functions. It may be specified as NULL if no value is necessary.
sd_bus_add_fallback_vtable() is similar to sd_bus_add_object_vtable(), but is used to register "fallback" attributes. When looking for an attribute declaration, bus object paths registered with sd_bus_add_object_vtable() are checked first. If no match is found, the fallback vtables are checked for each prefix of the bus object path, i.e. with the last slash-separated components successively removed. This allows the vtable to be used for an arbitrary number of dynamically created objects.
Parameter find is a function which is used to locate the target object based on the bus object path path. It must return 1 and set the ret_found output parameter if the object is found, return 0 if the object was not found, and return a negative errno-style error code or initialize the error structure ret_error on error. The pointer passed in ret_found will be used as the userdata parameter for the callback functions (offset by the offset offsets as specified in the vtable entries).
For both functions, a match slot is created internally. If the output parameter slot is NULL, a "floating" slot object is created, see sd_bus_slot_set_floating(3). Otherwise, a pointer to the slot object is returned. In that case, the reference to the slot object should be dropped when the vtable is not needed anymore, see sd_bus_slot_unref(3).
The sd_bus_vtable array¶
The array consists of the structures of type sd_bus_vtable, but it should never be filled in manually, but through one of the following macros:
SD_BUS_VTABLE_START(), SD_BUS_VTABLE_END
SD_BUS_METHOD_WITH_NAMES_OFFSET(), SD_BUS_METHOD_WITH_NAMES(), SD_BUS_METHOD_WITH_OFFSET(), SD_BUS_METHOD()
SD_BUS_METHOD_WITH_NAMES(), SD_BUS_METHOD_WITH_OFFSET(), and SD_BUS_METHOD() are variants which specify zero offset (userdata parameter is passed with no change), leave the names unset (i.e. no parameter names), or both.
SD_BUS_SIGNAL_WITH_NAMES(), SD_BUS_SIGNAL()
Equivalent to SD_BUS_SIGNAL_WITH_NAMES() with the names parameter unset (i.e. no parameter names).
SD_BUS_WRITABLE_PROPERTY(), SD_BUS_PROPERTY()
The setter and getter methods may be omitted (specified as NULL), if the property has one of the basic types or "as" in case of read-only properties. In those cases, the userdata and offset parameters must together point to valid variable of the corresponding type. A default setter and getters will be provided, which simply copy the argument between this variable and the message.
SD_BUS_PROPERTY() is used to define a read-only property.
SD_BUS_PARAM()
Flags¶
The flags parameter is used to specify a combination of D-Bus annotations[1].
SD_BUS_VTABLE_DEPRECATED
SD_BUS_VTABLE_HIDDEN
SD_BUS_VTABLE_UNPRIVILEGED
SD_BUS_VTABLE_METHOD_NO_REPLY
SD_BUS_VTABLE_PROPERTY_CONST, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE, SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
SD_BUS_VTABLE_PROPERTY_EXPLICIT
EXAMPLES¶
Example 1. Create a simple listener on the bus
//#include <errno.h> //#include <stdbool.h> //#include <stddef.h> //#include <stdlib.h> //#include <stdio.h> //#include <elogind/sd-bus.h> #define _cleanup_(f) __attribute__((cleanup(f))) typedef struct object {
char *name;
uint32_t number; } object; static int method(sd_bus_message *m, void *userdata, sd_bus_error *error) {
printf("Got called with userdata=%p\n", userdata);
return 1; } static const sd_bus_vtable vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_METHOD(
"Method1", "s", "s", method, 0),
SD_BUS_METHOD_WITH_NAMES_OFFSET(
"Method2",
"so", SD_BUS_PARAM(string) SD_BUS_PARAM(path),
"s", SD_BUS_PARAM(returnstring),
method, offsetof(object, number),
SD_BUS_VTABLE_DEPRECATED),
SD_BUS_WRITABLE_PROPERTY(
"AutomaticStringProperty", "s", NULL, NULL,
offsetof(object, name),
SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_WRITABLE_PROPERTY(
"AutomaticIntegerProperty", "u", NULL, NULL,
offsetof(object, number),
SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
SD_BUS_VTABLE_END }; #define check(x) ({ \
int r = x; \
errno = r < 0 ? -r : 0; \
printf(#x ": %m\n"); \
if (r < 0) \
return EXIT_FAILURE; \
}) int main(int argc, char **argv) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
sd_bus_default(&bus);
object object = { .number = 666 };
check((object.name = strdup("name")) != NULL);
check(sd_bus_add_object_vtable(bus, NULL, "/object",
"org.freedesktop.elogind.VtableExample",
vtable,
&object));
for (;;) {
check(sd_bus_wait(bus, UINT64_MAX));
check(sd_bus_process(bus, NULL));
}
free(object.name);
return 0; }
This creates a simple client on the bus (the user bus, when run as normal user). We may use the D-Bus org.freedesktop.DBus.Introspectable.Introspect call to acquire the XML description of the interface:
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> <node>
<interface name="org.freedesktop.DBus.Peer">
<method name="Ping"/>
<method name="GetMachineId">
<arg type="s" name="machine_uuid" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Introspectable">
<method name="Introspect">
<arg name="data" type="s" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Properties">
<method name="Get">
<arg name="interface" direction="in" type="s"/>
<arg name="property" direction="in" type="s"/>
<arg name="value" direction="out" type="v"/>
</method>
<method name="GetAll">
<arg name="interface" direction="in" type="s"/>
<arg name="properties" direction="out" type="a{sv}"/>
</method>
<method name="Set">
<arg name="interface" direction="in" type="s"/>
<arg name="property" direction="in" type="s"/>
<arg name="value" direction="in" type="v"/>
</method>
<signal name="PropertiesChanged">
<arg type="s" name="interface"/>
<arg type="a{sv}" name="changed_properties"/>
<arg type="as" name="invalidated_properties"/>
</signal>
</interface>
<interface name="org.freedesktop.elogind.VtableExample">
<method name="Method1">
<arg type="s" direction="in"/>
<arg type="s" direction="out"/>
</method>
<method name="Method2">
<arg type="s" name="string" direction="in"/>
<arg type="o" name="path" direction="in"/>
<arg type="s" name="returnstring" direction="out"/>
<annotation name="org.freedesktop.DBus.Deprecated" value="true"/>
</method>
<property name="AutomaticStringProperty" type="s" access="readwrite">
</property>
<property name="AutomaticIntegerProperty" type="u" access="readwrite">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="invalidates"/>
</property>
</interface> </node>
RETURN VALUE¶
On success, sd_bus_add_object_vtable and sd_bus_add_fallback_vtable calls return 0 or a positive integer. On failure, they return a negative errno-style error code.
Errors¶
Returned errors may indicate the following problems:
-EINVAL
-ENOPKG
-ECHILD
-ENOMEM
-EPROTOTYPE
-EEXIST
NOTES¶
These APIs are implemented as a shared library, which can be compiled and linked to with the libelogind pkg-config(1) file.
SEE ALSO¶
NOTES¶
- 1.
- D-Bus annotations
elogind 243.7 |