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 callback without
155       immediately sending a reply. This informs sd-bus this callback will
156       take responsibility for replying to the request without forcing the
157       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.
161
162       If a callback was invoked to handle a request that expects a reply and
163       the callback returns a negative value, the value is interpreted as a
164       negative errno-style error code and sent back to the caller as a D-Bus
165       error as if sd_bus_reply_method_errno(3) was called. Additionally, all
166       callbacks take a sd_bus_error output parameter that can be used to
167       provide more detailed error information. If ret_error is set when the
168       callback finishes, the corresponding D-Bus error is sent back to the
169       caller as if sd_bus_reply_method_error(3) was called. Any error stored
170       in ret_error takes priority over any negative values returned by the
171       same callback when determining which error to send back to the caller.
172       Use sd_bus_error_set(3) or one of its variants to set ret_error and
173       return a negative integer from a callback with a single function call.
174       To send an error reply after a callback has already finished, use
175       sd_bus_reply_method_errno(3) or one of its variants.
176
177       For all functions, a match slot is created internally. If the output
178       parameter slot is NULL, a "floating" slot object is created, see
179       sd_bus_slot_set_floating(3). Otherwise, a pointer to the slot object is
180       returned. In that case, the reference to the slot object should be
181       dropped when the vtable is not needed anymore, see
182       sd_bus_slot_unref(3).
183
184   The sd_bus_vtable array
185       The array consists of the structures of type sd_bus_vtable, but it
186       should never be filled in manually, but through one of the following
187       macros:
188
189       SD_BUS_VTABLE_START(), SD_BUS_VTABLE_END
190           Those must always be the first and last element.
191
192       SD_BUS_METHOD_WITH_ARGS_OFFSET(), SD_BUS_METHOD_WITH_ARGS()
193           Declare a D-Bus method with the name member, arguments args and
194           result result.  args expects a sequence of argument type/name pairs
195           wrapped in the SD_BUS_ARGS() macro. The elements at even indices in
196           this list describe the types of the method's arguments. The
197           method's parameter signature is the concatenation of all the string
198           literals at even indices in args. If a method has no parameters,
199           pass SD_BUS_NO_ARGS to args. The elements at uneven indices
200           describe the names of the method's arguments.  result expects a
201           sequence of type/name pairs wrapped in the SD_BUS_RESULT() macro in
202           the same format as SD_BUS_ARGS(). The method's result signature is
203           the concatenation of all the string literals at even indices in
204           result. If a method has no result, pass SD_BUS_NO_RESULT to result.
205           Note that argument types are expected to be quoted string literals
206           and argument names are expected to be unquoted string literals. See
207           below for a complete example.
208
209           The handler function handler must be of type
210           sd_bus_message_handler_t. It will be called to handle the incoming
211           messages that call this method. It receives a pointer that is the
212           userdata parameter passed to the registration function offset by
213           offset bytes. This may be used to pass pointers to different fields
214           in the same data structure to different methods in the same vtable.
215           To send a reply from handler, call sd_bus_reply_method_return(3)
216           with the message the callback was invoked with. Parameter flags is
217           a combination of flags, see below.
218
219           SD_BUS_METHOD_WITH_ARGS() is a shorthand for calling
220           SD_BUS_METHOD_WITH_ARGS_OFFSET() with an offset of zero.
221
222       SD_BUS_METHOD_WITH_NAMES_OFFSET(), SD_BUS_METHOD_WITH_NAMES(),
223       SD_BUS_METHOD_WITH_OFFSET(), SD_BUS_METHOD()
224           Declare a D-Bus method with the name member, parameter signature
225           signature, result signature result. Parameters in_names and
226           out_names specify the argument names of the input and output
227           arguments in the function signature.  in_names and out_names should
228           be created using the SD_BUS_PARAM() macro, see below. In all other
229           regards, this macro behaves exactly the same as
230           SD_BUS_METHOD_WITH_ARGS_OFFSET().
231
232           SD_BUS_METHOD_WITH_NAMES(), SD_BUS_METHOD_WITH_OFFSET(), and
233           SD_BUS_METHOD() are variants which specify zero offset (userdata
234           parameter is passed with no change), leave the names unset (i.e. no
235           parameter names), or both.
236
237           Prefer using SD_BUS_METHOD_WITH_ARGS_OFFSET() and
238           SD_BUS_METHOD_WITH_ARGS() over these macros as they allow
239           specifying argument types and names next to each other which is
240           less error-prone than first specifying all argument types followed
241           by specifying all argument names.
242
243       SD_BUS_SIGNAL_WITH_ARGS()
244           Declare a D-Bus signal with the name member and arguments args.
245           args expects a sequence of argument type/name pairs wrapped in the
246           SD_BUS_ARGS() macro. The elements at even indices in this list
247           describe the types of the signal's arguments. The signal's
248           parameter signature is the concatenation of all the string literals
249           at even indices in args. If a signal has no parameters, pass
250           SD_BUS_NO_ARGS to args. The elements at uneven indices describe the
251           names of the signal's arguments. Parameter flags is a combination
252           of flags. See below for a complete example.
253
254       SD_BUS_SIGNAL_WITH_NAMES(), SD_BUS_SIGNAL()
255           Declare a D-Bus signal with the name member, parameter signature
256           signature, and argument names names.  names should be created using
257           the SD_BUS_PARAM() macro, see below. Parameter flags is a
258           combination of flags, see below.
259
260           SD_BUS_SIGNAL() is equivalent to SD_BUS_SIGNAL_WITH_NAMES() with
261           the names parameter unset (i.e. no parameter names).
262
263           Prefer using SD_BUS_SIGNAL_WITH_ARGS() over these macros as it
264           allows specifying argument types and names next to each other which
265           is less error-prone than first specifying all argument types
266           followed by specifying all argument names.
267
268       SD_BUS_WRITABLE_PROPERTY(), SD_BUS_PROPERTY()
269           Declare a D-Bus property with the name member and value signature
270           signature. Parameters get and set are the getter and setter
271           methods. They are called with a pointer that is the userdata
272           parameter passed to the registration function offset by offset
273           bytes. This may be used pass pointers to different fields in the
274           same data structure to different setters and getters in the same
275           vtable. Parameter flags is a combination of flags, see below.
276
277           The setter and getter methods may be omitted (specified as NULL),
278           if the property is one of the basic types or "as" in case of
279           read-only properties. In those cases, the userdata and offset
280           parameters must together point to a valid variable of the
281           corresponding type. A default setter and getter will be provided,
282           which simply copy the argument between this variable and the
283           message.
284
285           SD_BUS_PROPERTY() is used to define a read-only property.
286
287       SD_BUS_PARAM()
288           Parameter names should be wrapped in this macro, see the example
289           below.
290
291   Flags
292       The flags parameter is used to specify a combination of D-Bus
293       annotations[1].
294
295       SD_BUS_VTABLE_DEPRECATED
296           Mark this vtable entry as deprecated using the
297           org.freedesktop.DBus.Deprecated annotation in introspection data.
298           If specified for SD_BUS_VTABLE_START(), the annotation is applied
299           to the enclosing interface.
300
301       SD_BUS_VTABLE_HIDDEN
302           Make this vtable entry hidden. It will not be shown in
303           introspection data. If specified for SD_BUS_VTABLE_START(), all
304           entries in the array are hidden.
305
306       SD_BUS_VTABLE_UNPRIVILEGED
307           Mark this vtable entry as unprivileged. If not specified, the
308           org.freedesktop.systemd1.Privileged annotation with value "true"
309           will be shown in introspection data.
310
311       SD_BUS_VTABLE_METHOD_NO_REPLY
312           Mark his vtable entry as a method that will not return a reply
313           using the org.freedesktop.DBus.Method.NoReply annotation in
314           introspection data.
315
316       SD_BUS_VTABLE_PROPERTY_CONST, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE,
317       SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
318           Those three flags correspond to different values of the
319           org.freedesktop.DBus.Property.EmitsChangedSignal annotation, which
320           specifies whether the
321           org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted
322           whenever the property changes.  SD_BUS_VTABLE_PROPERTY_CONST
323           corresponds to const and means that the property never changes
324           during the lifetime of the object it belongs to, so no signal needs
325           to be emitted.  SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE corresponds to
326           true and means that the signal is emitted.
327           SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION corresponds to
328           invalidates and means that the signal is emitted, but the value is
329           not included in the signal.
330
331       SD_BUS_VTABLE_PROPERTY_EXPLICIT
332           Mark this vtable property entry as requiring explicit request to
333           for the value to be shown (generally because the value is large or
334           slow to calculate). This entry cannot be combined with
335           SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE, and will not be shown in
336           property listings by default (e.g.  busctl introspect). This
337           corresponds to the org.freedesktop.systemd1.Explicit annotation in
338           introspection data.
339
340       SD_BUS_VTABLE_SENSITIVE
341           Mark this vtable method entry as processing sensitive data. When
342           set, incoming method call messages and their outgoing reply
343           messages are marked as sensitive using sd_bus_message_sensitive(3),
344           so that they are erased from memory when freed.
345
346       SD_BUS_VTABLE_ABSOLUTE_OFFSET
347           Mark this vtable method or property entry so that the user data
348           pointer passed to its associated handler functions is determined
349           slightly differently: instead of adding the offset parameter of the
350           entry to the user data pointer specified during vtable
351           registration, the offset is passed directly, converted to a
352           pointer, without taking the user data pointer specified during
353           vtable registration into account.
354

EXAMPLES

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

RETURN VALUE

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

NOTES

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

SEE ALSO

547       sd-bus(3), busctl(1), sd_bus_emit_properties_changed(3),
548       sd_bus_emit_object_added(3)
549

NOTES

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