SD_BUS_CALL_METHOD(3)
π
SD_BUS_CALL_METHOD(3) β the sd_bus_call_method family, explained
okay so bestie, welcome to the SD_BUS_CALL_METHOD(3) page β¨ this is the one manual page you need if you want to yell at a D-Bus method and get an answer back without hand-assembling a whole message like a Victorian orphan. it's giving "convenience function, but make it fashion" π
πΈ NAME πΈ
sd_bus_call_method, sd_bus_call_methodv, sd_bus_call_method_async, sd_bus_call_method_asyncv β these init a bus message object and fire off the corresponding D-Bus method call. like, both things, one function. we love a multitasker π
β¨ SYNOPSIS β¨
#include <systemd/sd-bus.h>
typedef int (*sd_bus_message_handler_t)(sd_bus_message *m,
void *userdata,
sd_bus_error *ret_error);
int sd_bus_call_method(sd_bus *bus, const char *destination,
const char *path, const char *interface,
const char *member, sd_bus_error *ret_error,
sd_bus_message **reply, const char *types, ...);
int sd_bus_call_methodv(sd_bus *bus, const char *destination,
const char *path, const char *interface,
const char *member, sd_bus_error *ret_error,
sd_bus_message **reply, const char *types,
va_list ap);
int sd_bus_call_method_async(sd_bus *bus, sd_bus_slot **slot,
const char *destination, const char *path,
const char *interface, const char *member,
sd_bus_message_handler_t callback,
void *userdata, const char *types, ...);
int sd_bus_call_method_asyncv(sd_bus *bus, sd_bus_slot **slot,
const char *destination, const char *path,
const char *interface, const char *member,
sd_bus_message_handler_t callback,
void *userdata, const char *types,
va_list ap);
π¦ DESCRIPTION π¦
sd_bus_call_method() is the convenience queen π she inits a bus message object and calls the corresponding D-Bus method, all in one go. basically she's three functions in a trench coat: sd_bus_message_new_method_call(3), sd_bus_message_append(3) and sd_bus_call(3), all smooshed into a single function call. iconic. no notes. π«Ά
sd_bus_call_method_async() is her chill sibling π same energy, but the call goes out asynchronously. she combines sd_bus_message_new_method_call(3), sd_bus_message_append(3) and sd_bus_call_async(3) into one function call, so you don't have to block and wait like it's 2011. main character energy fr π₯
β RETURN VALUE β
when it works? non-negative integer. slay π when it doesn't? a negative errno-style error code. sad but honest π
π Errors
for the full list of possible errors, go read the man pages for sd_bus_message_new_method_call(3), sd_bus_message_append(3), sd_bus_call(3) and sd_bus_call_async(3). they have the receipts π
π NOTES π
- these functions are available as a shared library, which you can compile against and link to using the
libsystemdpkg-config(1)file. yes,libsystemd. use it, love it. π - all functions listed here are thread-agnostic, and only a single thread may operate on a given object at any given time. different threads can hit the same object at different times, and multiple independent objects can absolutely be used from different threads in parallel. so like... share the object, not the moment π¦
- the code described here uses
getenv(3), which is literally declared not multi-thread-safe. that means if you're calling these functions, you must not callsetenv(3)from a parallel thread. bestie please, only callsetenv()in an early phase of the program, before any other threads have been started. i'm begging π
π EXAMPLES π
β¨ Example 1. Make a call to a D-Bus method that takes a single parameter β¨
/* SPDX-License-Identifier: MIT-0 */
/* This is equivalent to:
* busctl call org.freedesktop.systemd1 /org/freedesktop/systemd1 \
* org.freedesktop.systemd1.Manager GetUnitByPID $$
*
* Compile with 'cc print-unit-path-call-method.c -lsystemd'
*/
#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <systemd/sd-bus.h>
#define _cleanup_(f) __attribute__((cleanup(f)))
#define DESTINATION "org.freedesktop.systemd1"
#define PATH "/org/freedesktop/systemd1"
#define INTERFACE "org.freedesktop.systemd1.Manager"
#define MEMBER "GetUnitByPID"
static int log_error(int error, const char *message) {
fprintf(stderr, "%s: %s\n", message, strerror(-error));
return error;
}
int main(int argc, char **argv) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
int r;
r = sd_bus_open_system(&bus);
if (r < 0)
return log_error(r, "Failed to acquire bus");
r = sd_bus_call_method(bus, DESTINATION, PATH, INTERFACE, MEMBER, &error, &reply, "u", (unsigned) getpid());
if (r < 0)
return log_error(r, MEMBER " call failed");
const char *ans;
r = sd_bus_message_read(reply, "o", &ans);
if (r < 0)
return log_error(r, "Failed to read reply");
printf("Unit path is \"%s\".\n", ans);
return 0;
}
so what does this do? it defines a minimally useful program that opens a connection to the bus, calls a method, waits for the reply, and finally extracts and prints the answer. and it does actual error handling and proper memory management, so you can look your compiler in the eye ππ
πΈ HISTORY πΈ
sd_bus_call_method()andsd_bus_call_method_async()were added in version 221.sd_bus_call_methodv()andsd_bus_call_method_asyncv()were added in version 246.
(the glow-up was real and it happened in stages π¦)
π SEE ALSO π
systemd(1), sd-bus(3), sd_bus_message_new_method_call(3), sd_bus_message_append(3), sd_bus_call(3), sd_bus_set_property(3), sd_bus_emit_signal(3)
that's the whole page, bestie, you ate it up fr fr π this absolute banger of a manual page ships with systemd 261.3 β go forth, call your methods, handle your errnos, and remember: one thread per object at a time, or it's giving undefined chaos πβ¨
π¦ where this page comes from
- ubuntu stonking: libsystemd-dev 261.3-0ubuntu3 Β· LGPL-2.1-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms