From afb9c0c95817e687d27b9fa21d4e7db6075c583d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 21 Apr 2019 22:39:30 +0200 Subject: [PATCH] man: document sd_bus_add_{object,fallback}_vtable The interface provided by those two functions is huge, so this text could probably be made two or three times as long if all details were described. But I think it's a good start. --- man/rules/meson.build | 15 + man/sd-bus.xml | 1 + man/sd_bus_add_object_vtable.xml | 473 +++++++++++++++++++++++++++++++ man/vtable-example.c | 70 +++++ man/vtable-example.xml | 54 ++++ 5 files changed, 613 insertions(+) create mode 100644 man/sd_bus_add_object_vtable.xml create mode 100644 man/vtable-example.c create mode 100644 man/vtable-example.xml diff --git a/man/rules/meson.build b/man/rules/meson.build index 9674cbb30b..6894158466 100644 --- a/man/rules/meson.build +++ b/man/rules/meson.build @@ -115,6 +115,21 @@ manpages = [ 'sd_bus_match_signal', 'sd_bus_match_signal_async'], ''], + ['sd_bus_add_object_vtable', + '3', + ['SD_BUS_METHOD', + 'SD_BUS_METHOD_WITH_NAMES', + 'SD_BUS_METHOD_WITH_NAMES_OFFSET', + 'SD_BUS_METHOD_WITH_OFFSET', + 'SD_BUS_PARAM', + 'SD_BUS_PROPERTY', + 'SD_BUS_SIGNAL', + 'SD_BUS_SIGNAL_WITH_NAMES', + 'SD_BUS_VTABLE_END', + 'SD_BUS_VTABLE_START', + 'SD_BUS_WRITABLE_PROPERTY', + 'sd_bus_add_fallback_vtable'], + ''], ['sd_bus_attach_event', '3', ['sd_bus_detach_event', 'sd_bus_get_event'], ''], ['sd_bus_close', '3', ['sd_bus_flush'], ''], ['sd_bus_creds_get_pid', diff --git a/man/sd-bus.xml b/man/sd-bus.xml index 6c925e3161..e9a66d87dd 100644 --- a/man/sd-bus.xml +++ b/man/sd-bus.xml @@ -41,6 +41,7 @@ See sd_bus_add_match3, +sd_bus_add_object_vtable3, sd_bus_attach_event3, sd_bus_creds_get_pid3, sd_bus_creds_new_from_pid3, diff --git a/man/sd_bus_add_object_vtable.xml b/man/sd_bus_add_object_vtable.xml new file mode 100644 index 0000000000..92be236afd --- /dev/null +++ b/man/sd_bus_add_object_vtable.xml @@ -0,0 +1,473 @@ + + + + + + + + sd_bus_add_object_vtable + systemd + + + + sd_bus_add_object_vtable + 3 + + + + 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 + + + + + #include <systemd/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_object_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_floating3. + 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_unref3. + + + + The <structname>sd_bus_vtable</structname> 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 + + Those must always be the first and last element. + + + + SD_BUS_METHOD_WITH_NAMES_OFFSET() + SD_BUS_METHOD_WITH_NAMES() + SD_BUS_METHOD_WITH_OFFSET() + SD_BUS_METHOD() + + Declare a D-Bus method with the name member, parameter + signature signature, result signature result. + Parameters in_names and out_names specify the + argument names of the input and output arguments in the function signature. The handler function + handler must be of type sd_bus_message_handler_t. + It will be called to handle the incoming messages that call this method. It receives a pointer that + is the userdata parameter passed to the registration function offset by + offset bytes. This may be used to pass pointers to different fields in + the same data structure to different methods in the same + vtable. in_names and out_names should be + created using the SD_BUS_PARAM() macro, see below. Parameter + flags is a combination of flags, see below. + + 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() + + Declare a D-Bus signal with the name member, + parameter signature signature, and argument names + names. names should be + created using the SD_BUS_PARAM() macro, see below. + Parameter flags is a combination of flags, see below. + + + Equivalent to SD_BUS_SIGNAL_WITH_NAMES() with the + names paramater unset (i.e. no parameter names). + + + + + SD_BUS_WRITABLE_PROPERTY() + SD_BUS_PROPERTY() + + Declare a D-Bus property with the name member and value + signature signature. Parameters get and + set are the getter and setter methods. They are called with a pointer + that is the userdata parameter passed to the registration function + offset by offset bytes. This may be used pass pointers to different + fields in the same data structure to different setters and getters in the same vtable. Parameter + flags is a combination of flags, see below. + + 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() + Parameter names should be wrapped in this macro, see the example below. + + + + + + + Flags + + The flags parameter is used to specify a combination of + D-Bus annotations. + + + + + SD_BUS_VTABLE_DEPRECATED + + Mark this vtable entry as deprecated using the + org.freedesktop.DBus.Deprecated annotation in introspection data. If + specified for SD_BUS_VTABLE_START(), the annotation is applied to the + enclosing interface. + + + + SD_BUS_VTABLE_HIDDEN + + Make this vtable entry hidden. It will not be shown in introspection data. If + specified for SD_BUS_VTABLE_START(), all entries in the array are hidden. + + + + + + SD_BUS_VTABLE_UNPRIVILEGED + + Mark this vtable entry as unprivileged. If not specified, the + org.freedesktop.systemd1.Privileged annotation with value + true will be shown in introspection data. + + + + + SD_BUS_VTABLE_METHOD_NO_REPLY + + Mark his vtable entry as a method that will not return a reply using the + org.freedesktop.DBus.Method.NoReply annotation in introspection data. + + + + + SD_BUS_VTABLE_CONST + SD_BUS_VTABLE_EMITS_CHANGE + SD_BUS_VTABLE_EMITS_INVALIDATION + + Those three flags correspond to different values of the + org.freedesktop.DBus.Property.EmitsChangedSignal annotation, which specifies + whether the org.freedesktop.DBus.Properties.PropertiesChanged signal is + emitted whenever the property changes. SD_BUS_VTABLE_CONST corresponds to + const and means that the property never changes during the lifetime of the + object it belongs to, so no signal needs to be emitted. + SD_BUS_VTABLE_EMITS_CHANGE corresponds to true and means + that the signal is emitted. SD_BUS_VTABLE_EMITS_INVALIDATION corresponds to + invalides and means that the signal is emitted, but the value is not included + in the signal. + + + + + SD_BUS_VTABLE_PROPERTY_EXPLICIT + + Mark this vtable property entry as requiring explicit request to for the value to + be shown (generally because the value is large or slow to calculate). This entry cannot be combined + with SD_BUS_VTABLE_EMITS_CHANGE, and will not be shown in property listings by + default (e.g. busctl introspect). This corresponds to the + org.freedesktop.systemd1.Explicit annotation in introspection data. + + + + + + + + Examples + + + Create a simple listener on the bus + + + + 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: + + + + + + + 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 + + One of the required parameters is NULL or invalid. A reserved + D-Bus interface was passed as the interface parameter. + + + + -ENOPKG + + The bus cannot be resolved. + + + + -ECHILD + + The bus was created in a different process. + + + + -ENOMEM + + Memory allocation failed. + + + + -EPROTOTYPE + + sd_bus_add_object_vtable and + sd_bus_add_fallback_vtable have been both called + for the same bus object path, which is not allowed. + + + + -EEXIST + + This vtable has already been registered for this + interface and path. + + + + + + + + + + See Also + + + sd-bus3, + busctl1 + + + diff --git a/man/vtable-example.c b/man/vtable-example.c new file mode 100644 index 0000000000..a2a6cd18d7 --- /dev/null +++ b/man/vtable-example.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include +#include +#include + +#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.systemd.VtableExample", + vtable, + &object)); + + while (true) { + check(sd_bus_wait(bus, UINT64_MAX)); + check(sd_bus_process(bus, NULL)); + } + + free(object.name); + + return 0; +} diff --git a/man/vtable-example.xml b/man/vtable-example.xml new file mode 100644 index 0000000000..a3cdeae704 --- /dev/null +++ b/man/vtable-example.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +