1 /* SPDX-License-Identifier: CC0-1.0 */
2
3 #include <errno.h>
4 #include <stdbool.h>
5 #include <stddef.h>
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <systemd/sd-bus.h>
9
10 #define _cleanup_(f) __attribute__((cleanup(f)))
11
12 #define check(x) ({ \
13 int r = (x); \
14 errno = r < 0 ? -r : 0; \
15 printf(#x ": %m\n"); \
16 if (r < 0) \
17 return EXIT_FAILURE; \
18 })
19
20 typedef struct object {
21 char *name;
22 uint32_t number;
23 } object;
24
method(sd_bus_message * m,void * userdata,sd_bus_error * error)25 static int method(sd_bus_message *m, void *userdata, sd_bus_error *error) {
26 printf("Got called with userdata=%p\n", userdata);
27
28 if (sd_bus_message_is_method_call(m,
29 "org.freedesktop.systemd.VtableExample",
30 "Method4"))
31 return 1;
32
33 const char *string;
34 check(sd_bus_message_read(m, "s", &string));
35 check(sd_bus_reply_method_return(m, "s", string));
36
37 return 1;
38 }
39
40 static const sd_bus_vtable vtable[] = {
41 SD_BUS_VTABLE_START(0),
42 SD_BUS_METHOD(
43 "Method1", "s", "s", method, 0),
44 SD_BUS_METHOD_WITH_NAMES_OFFSET(
45 "Method2",
46 "so", SD_BUS_PARAM(string) SD_BUS_PARAM(path),
47 "s", SD_BUS_PARAM(returnstring),
48 method, offsetof(object, number),
49 SD_BUS_VTABLE_DEPRECATED),
50 SD_BUS_METHOD_WITH_ARGS_OFFSET(
51 "Method3",
52 SD_BUS_ARGS("s", string, "o", path),
53 SD_BUS_RESULT("s", returnstring),
54 method, offsetof(object, number),
55 SD_BUS_VTABLE_UNPRIVILEGED),
56 SD_BUS_METHOD_WITH_ARGS(
57 "Method4",
58 SD_BUS_NO_ARGS,
59 SD_BUS_NO_RESULT,
60 method,
61 SD_BUS_VTABLE_UNPRIVILEGED),
62 SD_BUS_SIGNAL(
63 "Signal1",
64 "so",
65 0),
66 SD_BUS_SIGNAL_WITH_NAMES(
67 "Signal2",
68 "so", SD_BUS_PARAM(string) SD_BUS_PARAM(path),
69 0),
70 SD_BUS_SIGNAL_WITH_ARGS(
71 "Signal3",
72 SD_BUS_ARGS("s", string, "o", path),
73 0),
74 SD_BUS_WRITABLE_PROPERTY(
75 "AutomaticStringProperty", "s", NULL, NULL,
76 offsetof(object, name),
77 SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
78 SD_BUS_WRITABLE_PROPERTY(
79 "AutomaticIntegerProperty", "u", NULL, NULL,
80 offsetof(object, number),
81 SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
82 SD_BUS_VTABLE_END
83 };
84
main(int argc,char ** argv)85 int main(int argc, char **argv) {
86 _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
87
88 sd_bus_default(&bus);
89
90 object object = { .number = 666 };
91 check((object.name = strdup("name")) != NULL);
92
93 check(sd_bus_add_object_vtable(bus, NULL,
94 "/org/freedesktop/systemd/VtableExample",
95 "org.freedesktop.systemd.VtableExample",
96 vtable,
97 &object));
98
99 check(sd_bus_request_name(bus,
100 "org.freedesktop.systemd.VtableExample",
101 0));
102
103 for (;;) {
104 check(sd_bus_wait(bus, UINT64_MAX));
105 check(sd_bus_process(bus, NULL));
106 }
107
108 check(sd_bus_release_name(bus, "org.freedesktop.systemd.VtableExample"));
109 free(object.name);
110
111 return 0;
112 }
113