[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