1SD_BUS_ADD_OBJECT(3)           sd_bus_add_object          SD_BUS_ADD_OBJECT(3)
2
3
4

NAME

6       sd_bus_add_object, sd_bus_add_fallback, sd_bus_add_object_vtable,
7       sd_bus_add_fallback_vtable, sd_bus_add_filter, SD_BUS_VTABLE_START,
8       SD_BUS_VTABLE_END, SD_BUS_METHOD_WITH_NAMES_OFFSET,
9       SD_BUS_METHOD_WITH_NAMES, SD_BUS_METHOD_WITH_OFFSET, SD_BUS_METHOD,
10       SD_BUS_SIGNAL_WITH_NAMES, SD_BUS_SIGNAL, SD_BUS_WRITABLE_PROPERTY,
11       SD_BUS_PROPERTY, SD_BUS_PARAM - Declare properties and methods for a
12       D-Bus path
13

SYNOPSIS

15       #include <systemd/sd-bus-vtable.h>
16
17
18       typedef int (*sd_bus_message_handler_t)(sd_bus_message *m,
19                                               void *userdata,
20                                               sd_bus_error *ret_error);
21
22       typedef int (*sd_bus_property_get_t)(sd_bus *bus, const char *path,
23                                            const char *interface,
24                                            const char *property,
25                                            sd_bus_message *reply,
26                                            void *userdata,
27                                            sd_bus_error *ret_error);
28
29       typedef int (*sd_bus_property_set_t)(sd_bus *bus, const char *path,
30                                            const char *interface,
31                                            const char *property,
32                                            sd_bus_message *value,
33                                            void *userdata,
34                                            sd_bus_error *ret_error);
35
36       typedef int (*sd_bus_object_find_t)(const char *path,
37                                           const char *interface,
38                                           void *userdata, void **ret_found,
39                                           sd_bus_error *ret_error);
40
41       int sd_bus_add_object(sd_bus *bus, sd_bus_slot **slot,
42                             const char *path,
43                             sd_bus_message_handler_t callback,
44                             void *userdata);
45
46       int sd_bus_add_fallback(sd_bus *bus, sd_bus_slot **slot,
47                               const char *path,
48                               sd_bus_message_handler_t callback,
49                               void *userdata);
50
51       int sd_bus_add_object_vtable(sd_bus *bus, sd_bus_slot **slot,
52                                    const char *path, const char *interface,
53                                    const sd_bus_vtable *vtable,
54                                    void *userdata);
55
56       int sd_bus_add_fallback_vtable(sd_bus *bus, sd_bus_slot **slot,
57                                      const char *prefix,
58                                      const char *interface,
59                                      const sd_bus_vtable *vtable,
60                                      sd_bus_object_find_t find,
61                                      void *userdata);
62
63       int sd_bus_add_filter(sd_bus *bus, sd_bus_slot **slot,
64                             sd_bus_message_handler_t callback,
65                             void *userdata);
66
67       SD_BUS_VTABLE_START(flags)
68
69       SD_BUS_VTABLE_END
70
71       SD_BUS_METHOD_WITH_ARGS_OFFSET( member, args, result, handler, offset,
72       flags)
73
74       SD_BUS_METHOD_WITH_ARGS( member, args, result, handler, flags)
75
76       SD_BUS_METHOD_WITH_NAMES_OFFSET( member, signature, in_names, result,
77       out_names, handler, offset, flags)
78
79       SD_BUS_METHOD_WITH_NAMES( member, signature, in_names, result,
80       out_names, handler, flags)
81
82       SD_BUS_METHOD_WITH_OFFSET( member, signature, result, handler, offset,
83       flags)
84
85       SD_BUS_METHOD( member, signature, result, handler, flags)
86
87       SD_BUS_SIGNAL_WITH_ARGS( member, args, flags)
88
89       SD_BUS_SIGNAL_WITH_NAMES( member, signature, names, flags)
90
91       SD_BUS_SIGNAL( member, signature, flags)
92
93       SD_BUS_WRITABLE_PROPERTY( member, signature, get, set, offset, flags)
94
95       SD_BUS_PROPERTY( member, signature, get, offset, flags)
96
97       SD_BUS_PARAM(name) SD_BUS_ARGS(...)  SD_BUS_RESULT(...)  SD_BUS_NO_ARGS
98       SD_BUS_NO_RESULT
99

DESCRIPTION

101       sd_bus_add_object_vtable() is used to declare attributes for the object
102       path path connected to the bus connection bus under the interface
103       interface. The table vtable may contain property declarations using
104       SD_BUS_PROPERTY() or SD_BUS_WRITABLE_PROPERTY(), method declarations
105       using SD_BUS_METHOD(), SD_BUS_METHOD_WITH_NAMES(),
106       SD_BUS_METHOD_WITH_OFFSET(), or SD_BUS_METHOD_WITH_NAMES_OFFSET(), and
107       signal declarations using SD_BUS_SIGNAL_WITH_NAMES() or
108       SD_BUS_SIGNAL(), see below. The userdata parameter contains a pointer
109       that will be passed to various callback functions. It may be specified
110       as NULL if no value is necessary. An interface can have any number of
111       vtables attached to it.
112
113       sd_bus_add_fallback_vtable() is similar to sd_bus_add_object_vtable(),
114       but is used to register "fallback" attributes. When looking for an
115       attribute declaration, bus object paths registered with
116       sd_bus_add_object_vtable() are checked first. If no match is found, the
117       fallback vtables are checked for each prefix of the bus object path,
118       i.e. with the last slash-separated components successively removed.
119       This allows the vtable to be used for an arbitrary number of
120       dynamically created objects.
121
122       Parameter find is a function which is used to locate the target object
123       based on the bus object path path. It must return 1 and set the
124       ret_found output parameter if the object is found, return 0 if the
125       object was not found, and return a negative errno-style error code or
126       initialize the error structure ret_error on error. The pointer passed
127       in ret_found will be used as the userdata parameter for the callback
128       functions (offset by the offset offsets as specified in the vtable
129       entries).
130
131       sd_bus_add_object() attaches a callback directly to the object path
132       path. An object path can have any number of callbacks attached to it.
133       Each callback is prepended to the list of callbacks which are always
134       called in order.  sd_bus_add_fallback() is similar to
135       sd_bus_add_object() but applies to fallback paths instead.
136
137       sd_bus_add_filter() installs a callback that is invoked for each
138       incoming D-Bus message. Filters can be used to handle logic common to
139       all messages received by a service (e.g. authentication or
140       authorization).
141
142       When a request is received, any associated callbacks are called
143       sequentially until a callback returns a non-zero integer. Return zero
144       from a callback to give other callbacks the chance to process the
145       request. Callbacks are called in the following order: first, global
146       callbacks installed with sd_bus_add_filter() are called. Second,
147       callbacks attached directly to the request object path are called,
148       followed by any D-Bus method callbacks attached to the request object
149       path, interface and member. Finally, the property callbacks attached to
150       the request object path, interface and member are called. If the final
151       callback returns zero, an error reply is sent back to the caller
152       indicating no matching object for the request was found.
153
154       Note that you can return a positive integer from a method callback
155       without immediately sending a reply. This informs sd-bus this callback
156       will take responsibility for replying to the request without forcing
157       the callback to produce a reply immediately. This allows a callback to
158       perform any number of asynchronous operations required to construct a
159       reply. However, if producing a reply takes too long, the method call
160       will time out at the caller. This is only available to methods and not
161       properties.
162
163       If a callback was invoked to handle a request that expects a reply and
164       the callback returns a negative value, the value is interpreted as a
165       negative errno-style error code and sent back to the caller as a D-Bus
166       error as if sd_bus_reply_method_errno(3) was called. Additionally, all
167       callbacks take a sd_bus_error output parameter that can be used to
168       provide more detailed error information. If ret_error is set when the
169       callback finishes, the corresponding D-Bus error is sent back to the
170       caller as if sd_bus_reply_method_error(3) was called. Any error stored
171       in ret_error takes priority over any negative values returned by the
172       same callback when determining which error to send back to the caller.
173       Use sd_bus_error_set(3) or one of its variants to set ret_error and
174       return a negative integer from a callback with a single function call.
175       To send an error reply after a callback has already finished, use
176       sd_bus_reply_method_errno(3) or one of its variants.
177
178       For all functions, a match slot is created internally. If the output
179       parameter slot is NULL, a "floating" slot object is created, see
180       sd_bus_slot_set_floating(3). Otherwise, a pointer to the slot object is
181       returned. In that case, the reference to the slot object should be
182       dropped when the vtable is not needed anymore, see
183       sd_bus_slot_unref(3).
184
185   The sd_bus_vtable array
186       The array consists of the structures of type sd_bus_vtable, but it
187       should never be filled in manually, but through one of the following
188       macros:
189
190       SD_BUS_VTABLE_START(), SD_BUS_VTABLE_END
191           Those must always be the first and last element.
192
193       SD_BUS_METHOD_WITH_ARGS_OFFSET(), SD_BUS_METHOD_WITH_ARGS()
194           Declare a D-Bus method with the name member, arguments args and
195           result result.  args expects a sequence of argument type/name pairs
196           wrapped in the SD_BUS_ARGS() macro. The elements at even indices in
197           this list describe the types of the method's arguments. The
198           method's parameter signature is the concatenation of all the string
199           literals at even indices in args. If a method has no parameters,
200           pass SD_BUS_NO_ARGS to args. The elements at uneven indices
201           describe the names of the method's arguments.  result expects a
202           sequence of type/name pairs wrapped in the SD_BUS_RESULT() macro in
203           the same format as SD_BUS_ARGS(). The method's result signature is
204           the concatenation of all the string literals at even indices in
205           result. If a method has no result, pass SD_BUS_NO_RESULT to result.
206           Note that argument types are expected to be quoted string literals
207           and argument names are expected to be unquoted string literals. See
208           below for a complete example.
209
210           The handler function handler must be of type
211           sd_bus_message_handler_t. It will be called to handle the incoming
212           messages that call this method. It receives a pointer that is the
213           userdata parameter passed to the registration function offset by
214           offset bytes. This may be used to pass pointers to different fields
215           in the same data structure to different methods in the same vtable.
216           To send a reply from handler, call sd_bus_reply_method_return(3)
217           with the message the callback was invoked with. Parameter flags is
218           a combination of flags, see below.
219
220           SD_BUS_METHOD_WITH_ARGS() is a shorthand for calling
221           SD_BUS_METHOD_WITH_ARGS_OFFSET() with an offset of zero.
222
223       SD_BUS_METHOD_WITH_NAMES_OFFSET(), SD_BUS_METHOD_WITH_NAMES(),
224       SD_BUS_METHOD_WITH_OFFSET(), SD_BUS_METHOD()
225           Declare a D-Bus method with the name member, parameter signature
226           signature, result signature result. Parameters in_names and
227           out_names specify the argument names of the input and output
228           arguments in the function signature.  in_names and out_names should
229           be created using the SD_BUS_PARAM() macro, see below. In all other
230           regards, this macro behaves exactly the same as
231           SD_BUS_METHOD_WITH_ARGS_OFFSET().
232
233           SD_BUS_METHOD_WITH_NAMES(), SD_BUS_METHOD_WITH_OFFSET(), and
234           SD_BUS_METHOD() are variants which specify zero offset (userdata
235           parameter is passed with no change), leave the names unset (i.e. no
236           parameter names), or both.
237
238           Prefer using SD_BUS_METHOD_WITH_ARGS_OFFSET() and
239           SD_BUS_METHOD_WITH_ARGS() over these macros as they allow
240           specifying argument types and names next to each other which is
241           less error-prone than first specifying all argument types followed
242           by specifying all argument names.
243
244       SD_BUS_SIGNAL_WITH_ARGS()
245           Declare a D-Bus signal with the name member and arguments args.
246           args expects a sequence of argument type/name pairs wrapped in the
247           SD_BUS_ARGS() macro. The elements at even indices in this list
248           describe the types of the signal's arguments. The signal's
249           parameter signature is the concatenation of all the string literals
250           at even indices in args. If a signal has no parameters, pass
251           SD_BUS_NO_ARGS to args. The elements at uneven indices describe the
252           names of the signal's arguments. Parameter flags is a combination
253           of flags. See below for a complete example.
254
255       SD_BUS_SIGNAL_WITH_NAMES(), SD_BUS_SIGNAL()
256           Declare a D-Bus signal with the name member, parameter signature
257           signature, and argument names names.  names should be created using
258           the SD_BUS_PARAM() macro, see below. Parameter flags is a
259           combination of flags, see below.
260
261           SD_BUS_SIGNAL() is equivalent to SD_BUS_SIGNAL_WITH_NAMES() with
262           the names parameter unset (i.e. no parameter names).
263
264           Prefer using SD_BUS_SIGNAL_WITH_ARGS() over these macros as it
265           allows specifying argument types and names next to each other which
266           is less error-prone than first specifying all argument types
267           followed by specifying all argument names.
268
269       SD_BUS_WRITABLE_PROPERTY(), SD_BUS_PROPERTY()
270           Declare a D-Bus property with the name member and value signature
271           signature. Parameters get and set are the getter and setter
272           methods. They are called with a pointer that is the userdata
273           parameter passed to the registration function offset by offset
274           bytes. This may be used pass pointers to different fields in the
275           same data structure to different setters and getters in the same
276           vtable. Parameter flags is a combination of flags, see below.
277
278           The setter and getter methods may be omitted (specified as NULL),
279           if the property is one of the basic types or "as" in case of
280           read-only properties. In those cases, the userdata and offset
281           parameters must together point to a valid variable of the
282           corresponding type. A default setter and getter will be provided,
283           which simply copy the argument between this variable and the
284           message.
285
286           SD_BUS_PROPERTY() is used to define a read-only property.
287
288       SD_BUS_PARAM()
289           Parameter names should be wrapped in this macro, see the example
290           below.
291
292   Flags
293       The flags parameter is used to specify a combination of D-Bus
294       annotations[1].
295
296       SD_BUS_VTABLE_DEPRECATED
297           Mark this vtable entry as deprecated using the
298           org.freedesktop.DBus.Deprecated annotation in introspection data.
299           If specified for SD_BUS_VTABLE_START(), the annotation is applied
300           to the enclosing interface.
301
302       SD_BUS_VTABLE_HIDDEN
303           Make this vtable entry hidden. It will not be shown in
304           introspection data. If specified for SD_BUS_VTABLE_START(), all
305           entries in the array are hidden.
306
307       SD_BUS_VTABLE_UNPRIVILEGED
308           Mark this vtable entry as unprivileged. If not specified, the
309           org.freedesktop.systemd1.Privileged annotation with value "true"
310           will be shown in introspection data.
311
312       SD_BUS_VTABLE_METHOD_NO_REPLY
313           Mark this vtable entry as a method that will not return a reply
314           using the org.freedesktop.DBus.Method.NoReply annotation in
315           introspection data.
316
317       SD_BUS_VTABLE_PROPERTY_CONST, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE,
318       SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
319           Those three flags correspond to different values of the
320           org.freedesktop.DBus.Property.EmitsChangedSignal annotation, which
321           specifies whether the
322           org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted
323           whenever the property changes.  SD_BUS_VTABLE_PROPERTY_CONST
324           corresponds to const and means that the property never changes
325           during the lifetime of the object it belongs to, so no signal needs
326           to be emitted.  SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE corresponds to
327           true and means that the signal is emitted.
328           SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION corresponds to
329           invalidates and means that the signal is emitted, but the value is
330           not included in the signal.
331
332       SD_BUS_VTABLE_PROPERTY_EXPLICIT
333           Mark this vtable property entry as requiring explicit request to
334           for the value to be shown (generally because the value is large or
335           slow to calculate). This entry cannot be combined with
336           SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE, and will not be shown in
337           property listings by default (e.g.  busctl introspect). This
338           corresponds to the org.freedesktop.systemd1.Explicit annotation in
339           introspection data.
340
341       SD_BUS_VTABLE_SENSITIVE
342           Mark this vtable method entry as processing sensitive data. When
343           set, incoming method call messages and their outgoing reply
344           messages are marked as sensitive using sd_bus_message_sensitive(3),
345           so that they are erased from memory when freed.
346
347       SD_BUS_VTABLE_ABSOLUTE_OFFSET
348           Mark this vtable method or property entry so that the user data
349           pointer passed to its associated handler functions is determined
350           slightly differently: instead of adding the offset parameter of the
351           entry to the user data pointer specified during vtable
352           registration, the offset is passed directly, converted to a
353           pointer, without taking the user data pointer specified during
354           vtable registration into account.
355

EXAMPLES

357       Example 1. Create a simple listener on the bus
358
359           #include <errno.h>
360           #include <stdbool.h>
361           #include <stddef.h>
362           #include <stdlib.h>
363           #include <stdio.h>
364           #include <systemd/sd-bus.h>
365
366           #define _cleanup_(f) __attribute__((cleanup(f)))
367
368           typedef struct object {
369             char *name;
370             uint32_t number;
371           } object;
372
373           static int method(sd_bus_message *m, void *userdata, sd_bus_error *error) {
374             printf("Got called with userdata=%p\n", userdata);
375             return 1;
376           }
377
378           static const sd_bus_vtable vtable[] = {
379                   SD_BUS_VTABLE_START(0),
380                   SD_BUS_METHOD(
381                       "Method1", "s", "s", method, 0),
382                   SD_BUS_METHOD_WITH_NAMES_OFFSET(
383                       "Method2",
384                       "so", SD_BUS_PARAM(string) SD_BUS_PARAM(path),
385                       "s", SD_BUS_PARAM(returnstring),
386                       method, offsetof(object, number),
387                       SD_BUS_VTABLE_DEPRECATED),
388                   SD_BUS_METHOD_WITH_ARGS_OFFSET(
389                       "Method3",
390                       SD_BUS_ARGS("s", string, "o", path),
391                       SD_BUS_RESULT("s", returnstring),
392                       method, offsetof(object, number),
393                       SD_BUS_VTABLE_UNPRIVILEGED),
394                   SD_BUS_METHOD_WITH_ARGS(
395                       "Method4",
396                       SD_BUS_NO_ARGS,
397                       SD_BUS_NO_RESULT,
398                       method,
399                       SD_BUS_VTABLE_UNPRIVILEGED),
400                   SD_BUS_SIGNAL(
401                       "Signal1",
402                       "so",
403                       0),
404                   SD_BUS_SIGNAL_WITH_NAMES(
405                       "Signal2",
406                       "so", SD_BUS_PARAM(string) SD_BUS_PARAM(path),
407                       0),
408                   SD_BUS_SIGNAL_WITH_ARGS(
409                       "Signal3",
410                       SD_BUS_ARGS("s", string, "o", path),
411                       0),
412                   SD_BUS_WRITABLE_PROPERTY(
413                       "AutomaticStringProperty", "s", NULL, NULL,
414                       offsetof(object, name),
415                       SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
416                   SD_BUS_WRITABLE_PROPERTY(
417                       "AutomaticIntegerProperty", "u", NULL, NULL,
418                       offsetof(object, number),
419                       SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
420                   SD_BUS_VTABLE_END
421           };
422
423           #define check(x) ({                             \
424             int r = x;                                    \
425             errno = r < 0 ? -r : 0;                       \
426             printf(#x ": %m\n");                          \
427             if (r < 0)                                    \
428               return EXIT_FAILURE;                        \
429             })
430
431           int main(int argc, char **argv) {
432             _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
433
434             sd_bus_default(&bus);
435
436             object object = { .number = 666 };
437             check((object.name = strdup("name")) != NULL);
438
439             check(sd_bus_add_object_vtable(bus, NULL, "/object",
440                                            "org.freedesktop.systemd.VtableExample",
441                                            vtable,
442                                            &object));
443
444             for (;;) {
445               check(sd_bus_wait(bus, UINT64_MAX));
446               check(sd_bus_process(bus, NULL));
447             }
448
449             free(object.name);
450
451             return 0;
452           }
453
454       This creates a simple client on the bus (the user bus, when run as
455       normal user). We may use the D-Bus
456       org.freedesktop.DBus.Introspectable.Introspect call to acquire the XML
457       description of the interface:
458
459           <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
460           "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
461           <node>
462            <interface name="org.freedesktop.DBus.Peer">
463             <method name="Ping"/>
464             <method name="GetMachineId">
465              <arg type="s" name="machine_uuid" direction="out"/>
466             </method>
467            </interface>
468            <interface name="org.freedesktop.DBus.Introspectable">
469             <method name="Introspect">
470              <arg name="data" type="s" direction="out"/>
471             </method>
472            </interface>
473            <interface name="org.freedesktop.DBus.Properties">
474             <method name="Get">
475              <arg name="interface" direction="in" type="s"/>
476              <arg name="property" direction="in" type="s"/>
477              <arg name="value" direction="out" type="v"/>
478             </method>
479             <method name="GetAll">
480              <arg name="interface" direction="in" type="s"/>
481              <arg name="properties" direction="out" type="a{sv}"/>
482             </method>
483             <method name="Set">
484              <arg name="interface" direction="in" type="s"/>
485              <arg name="property" direction="in" type="s"/>
486              <arg name="value" direction="in" type="v"/>
487             </method>
488             <signal name="PropertiesChanged">
489              <arg type="s" name="interface"/>
490              <arg type="a{sv}" name="changed_properties"/>
491              <arg type="as" name="invalidated_properties"/>
492             </signal>
493            </interface>
494            <interface name="org.freedesktop.systemd.VtableExample">
495             <method name="Method1">
496              <arg type="s" direction="in"/>
497              <arg type="s" direction="out"/>
498             </method>
499             <method name="Method2">
500              <arg type="s" name="string" direction="in"/>
501              <arg type="o" name="path" direction="in"/>
502              <arg type="s" name="returnstring" direction="out"/>
503              <annotation name="org.freedesktop.DBus.Deprecated" value="true"/>
504             </method>
505             <property name="AutomaticStringProperty" type="s" access="readwrite">
506             </property>
507             <property name="AutomaticIntegerProperty" type="u" access="readwrite">
508              <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="invalidates"/>
509             </property>
510            </interface>
511           </node>
512
513

RETURN VALUE

515       On success, sd_bus_add_object_vtable() and sd_bus_add_fallback_vtable()
516       return a non-negative integer. On failure, they return a negative
517       errno-style error code.
518
519   Errors
520       Returned errors may indicate the following problems:
521
522       -EINVAL
523           One of the required parameters is NULL or invalid. A reserved D-Bus
524           interface was passed as the interface parameter.
525
526       -ENOPKG
527           The bus cannot be resolved.
528
529       -ECHILD
530           The bus was created in a different process.
531
532       -ENOMEM
533           Memory allocation failed.
534
535       -EPROTOTYPE
536           sd_bus_add_object_vtable() and sd_bus_add_fallback_vtable() have
537           been both called for the same bus object path, which is not
538           allowed.
539
540       -EEXIST
541           This vtable has already been registered for this interface and
542           path.
543

NOTES

545       These APIs are implemented as a shared library, which can be compiled
546       and linked to with the libsystemd pkg-config(1) file.
547

SEE ALSO

549       sd-bus(3), busctl(1), sd_bus_emit_properties_changed(3),
550       sd_bus_emit_object_added(3)
551

NOTES

553        1. D-Bus annotations
554           https://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format
555
556
557
558systemd 249                                               SD_BUS_ADD_OBJECT(3)
Impressum