mirror of
https://github.com/systemd/systemd.git
synced 2024-12-29 15:22:07 +03:00
0cfb00d9da
The methods published by the example have a reply in the signature, but the code was not sending any, so the client gets stuck waiting for a response that doesn't arrive. Echo back the input string. Update the object path to follow what would be the canonical format. Request a service name on the bus, so that the code can be dropped in a service and it can be dbus-activatable. It also makes it easier to see on busctl list.
113 lines
3.3 KiB
C
113 lines
3.3 KiB
C
/* SPDX-License-Identifier: CC0-1.0 */
|
|
|
|
#include <errno.h>
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <systemd/sd-bus.h>
|
|
|
|
#define _cleanup_(f) __attribute__((cleanup(f)))
|
|
|
|
#define check(x) ({ \
|
|
int r = (x); \
|
|
errno = r < 0 ? -r : 0; \
|
|
printf(#x ": %m\n"); \
|
|
if (r < 0) \
|
|
return EXIT_FAILURE; \
|
|
})
|
|
|
|
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);
|
|
|
|
if (sd_bus_message_is_method_call(m,
|
|
"org.freedesktop.systemd.VtableExample",
|
|
"Method4"))
|
|
return 1;
|
|
|
|
const char *string;
|
|
check(sd_bus_message_read(m, "s", &string));
|
|
check(sd_bus_reply_method_return(m, "s", string));
|
|
|
|
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_METHOD_WITH_ARGS_OFFSET(
|
|
"Method3",
|
|
SD_BUS_ARGS("s", string, "o", path),
|
|
SD_BUS_RESULT("s", returnstring),
|
|
method, offsetof(object, number),
|
|
SD_BUS_VTABLE_UNPRIVILEGED),
|
|
SD_BUS_METHOD_WITH_ARGS(
|
|
"Method4",
|
|
SD_BUS_NO_ARGS,
|
|
SD_BUS_NO_RESULT,
|
|
method,
|
|
SD_BUS_VTABLE_UNPRIVILEGED),
|
|
SD_BUS_SIGNAL(
|
|
"Signal1",
|
|
"so",
|
|
0),
|
|
SD_BUS_SIGNAL_WITH_NAMES(
|
|
"Signal2",
|
|
"so", SD_BUS_PARAM(string) SD_BUS_PARAM(path),
|
|
0),
|
|
SD_BUS_SIGNAL_WITH_ARGS(
|
|
"Signal3",
|
|
SD_BUS_ARGS("s", string, "o", path),
|
|
0),
|
|
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
|
|
};
|
|
|
|
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,
|
|
"/org/freedesktop/systemd/VtableExample",
|
|
"org.freedesktop.systemd.VtableExample",
|
|
vtable,
|
|
&object));
|
|
|
|
check(sd_bus_request_name(bus,
|
|
"org.freedesktop.systemd.VtableExample",
|
|
0));
|
|
|
|
for (;;) {
|
|
check(sd_bus_wait(bus, UINT64_MAX));
|
|
check(sd_bus_process(bus, NULL));
|
|
}
|
|
|
|
check(sd_bus_release_name(bus, "org.freedesktop.systemd.VtableExample"));
|
|
free(object.name);
|
|
|
|
return 0;
|
|
}
|