[systemd-devel] sd_bus_process semantics
Mathis MARION
mamarion1 at silabs.com
Fri Jul 22 10:02:26 UTC 2022
Hello,
I am trying to retrieve an sd_bus_message using the 'ret' argument of
sd_bus_process().
The documentation says the following:
sd_bus_process() processes at most one incoming message per call. If
the parameter ret is not NULL and the call processed a message, *ret
is set to this message.
I declared a method, and called it from outside my program. I am seeing
that my method is being executed, but the message returned in 'ret' is
NULL. Is this a normal behavior? If so the doc seems unclear to me.
Here is my full test program:
#include <systemd/sd-bus.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <poll.h>
static int dbus_test_method(sd_bus_message *m, void *userdata,
sd_bus_error *ret_error)
{
const char *str;
int ret;
ret = sd_bus_message_read(m, "s", &str);
if (ret < 0)
return sd_bus_error_set_errno(ret_error, -ret);
printf("test_method: %s\n", str);
sd_bus_reply_method_return(m, NULL);
return 0;
}
static const sd_bus_vtable vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_METHOD("TestMethod", "s", NULL, dbus_test_method, 0),
SD_BUS_VTABLE_END
};
int main()
{
struct sd_bus_message *m;
struct sd_bus *bus;
struct pollfd fds;
int ret;
ret = sd_bus_default_user(&bus);
if (ret < 0) {
printf("sd_bus_default_user: %s\n", strerror(-ret));
return EXIT_FAILURE;
}
ret = sd_bus_add_object_vtable(bus, NULL, "/marionm/test",
"marionm.test", vtable, NULL);
if (ret < 0) {
printf("sd_bus_add_object_vtable: %s\n", strerror(-ret));
return EXIT_FAILURE;
}
ret = sd_bus_request_name(bus, "marionm.test",
SD_BUS_NAME_ALLOW_REPLACEMENT | SD_BUS_NAME_REPLACE_EXISTING);
if (ret < 0) {
printf("sd_bus_request_name: %s\n", strerror(-ret));
return EXIT_FAILURE;
}
fds.events = POLLIN;
fds.fd = sd_bus_get_fd(bus);
if (fds.fd < 0) {
printf("sd_bus_get_fd: %s\n", strerror(-ret));
return EXIT_FAILURE;
}
while (true) {
ret = poll(&fds, 1, -1);
if (ret < 0) {
printf("poll: %m\n");
return EXIT_FAILURE;
}
ret = sd_bus_process(bus, &m);
if (ret < 0) {
printf("sd_bus_process: %s\n", strerror(-ret));
return EXIT_FAILURE;
}
if (sd_bus_message_is_method_call(m, NULL, NULL))
printf("%p\n", m);
}
}
I compiled it with 'gcc -lsystemd'.
From another terminal I ran:
busctl --user call marionm.test /marionm/test marionm.test TestMethod s foo
Here is the resulting trace:
test_method: foo
m: (nil)
I expected to retrieve the message that was processed in
dbus_test_method. I can get into why I'd like to retrieve
the message here if needed, but it doesn't change the issue.
I am running Debian 11, and systemd v247.3
More information about the systemd-devel
mailing list