SD_BUS_MESSAGE_READ(3)
okay bestie, you're looking at SD_BUS_MESSAGE_READ(3) and it's literally the page where you learn how to pull a whole lil sequence of values out of a D-Bus message without losing the plot π
β¨
πΈ NAME πΈ
sd_bus_message_read, sd_bus_message_readv, sd_bus_message_peek_type β read a sequence of values from a message, no cap π«Ά
π¦ SYNOPSIS π¦
#include <systemd/sd-bus.h>
int sd_bus_message_read(sd_bus_message *m, const char *types, ...);
int sd_bus_message_readv(sd_bus_message *m, const char *types,
va_list ap);
int sd_bus_message_peek_type(sd_bus_message *m, char *type,
const char **contents);
π DESCRIPTION π
okay so sd_bus_message_read() reads a sequence of fields from the D-Bus message object m, and yes bestie, it advances the read position in the message. The type string types describes the types of items expected in the message and the field arguments that follow it. The type string may be NULL or empty, and in that case literally nothing gets read π«
The type string is composed of the elements described in sd_bus_message_append(3) β so that's basic types and container types, iykyk π It must contain zero or more single "complete types". The type string is NUL-terminated, periodt.
For each type specified in the type string, one or more arguments need to be specified after the types parameter, in the same order. The arguments must be pointers to appropriate types β a pointer to int8_t for a "y" in the type string, a pointer to int32_t for an "i", a pointer to const char* for an "s", and so on β and those get set based on the values in the message β¨
As an exception, in case of array and variant types, the first argument is an "input" argument that further specifies how the message should be read. Peep the table below for a complete list of allowed arguments and their types π
bestie, this next bit is important: if the basic type is a pointer (e.g., const char * in the case of a string), the argument is a pointer to a pointer, and also the pointer value that is written is only borrowed β the contents must be copied if they are to be used after the end of the message's lifetime. no cap, do not just keep that pointer chilling past the message's whole existence π
and if the type is "h" (UNIX file descriptor), the descriptor is not duplicated by this call, and the returned descriptor remains in possession of the message object. The caller needs to duplicate it in order to keep an open reference to it after the message object is freed π
Each argument may also be NULL, in which case the value is read and ignored π
π Table 1. Item type specifiers π
okay bestie, this is the cheat sheet you're gonna bookmark. every specifier string, the constant it maps to, what it means, and exactly what type your pointer argument has to be. no cap, the pointer types are the part people get wrong. π
"y"βSD_BUS_TYPE_BYTEβ an 8-bit unsigned integer. first arg type:uint8_t *."b"βSD_BUS_TYPE_BOOLEANβ a boolean. first arg type:int *(NB: notbool *π« like pls do not)."n"βSD_BUS_TYPE_INT16β a 16-bit signed integer. first arg type:int16_t *."q"βSD_BUS_TYPE_UINT16β a 16-bit unsigned integer. first arg type:uint16_t *."i"βSD_BUS_TYPE_INT32β a 32-bit signed integer. first arg type:int32_t *."u"βSD_BUS_TYPE_UINT32β a 32-bit unsigned integer. first arg type:uint32_t *."x"βSD_BUS_TYPE_INT64β a 64-bit signed integer. first arg type:int64_t *."t"βSD_BUS_TYPE_UINT64β a 64-bit unsigned integer. first arg type:uint64_t *."d"βSD_BUS_TYPE_DOUBLEβ an IEEE 754 double precision floating-point. first arg type:double *."s"βSD_BUS_TYPE_STRINGβ a UTF-8 string. first arg type:const char **."o"βSD_BUS_TYPE_OBJECT_PATHβ a D-Bus object path string. first arg type:const char **."g"βSD_BUS_TYPE_SIGNATUREβ a D-Bus signature string. first arg type:const char **."h"βSD_BUS_TYPE_UNIX_FDβ a UNIX file descriptor. first arg type:int *."a"βSD_BUS_TYPE_ARRAYβ an array. first arg type:int, which specifies the expected length n of the array. after that come n sets of arguments appropriate for the array element type π¦"v"βSD_BUS_TYPE_VARIANTβ a variant. first arg type: a signature string. after that come arguments appropriate for the types specified by the signature β¨"("βSD_BUS_TYPE_STRUCT_BEGINβ described as array start. the arguments are those appropriate for the structure elements.")"βSD_BUS_TYPE_STRUCT_ENDβ described as array end. the arguments are those appropriate for the structure elements."{"βSD_BUS_TYPE_DICT_ENTRY_BEGINβ dictionary entry start. first arg: arguments appropriate for the first type in the pair. second: arguments appropriate for the second type in the pair π"}"βSD_BUS_TYPE_DICT_ENTRY_ENDβ dictionary entry end. first arg: arguments appropriate for the first type in the pair. second: arguments appropriate for the second type in the pair π
heads up bestie: if objects of the specified types are not present at the current position in the message, an error is returned. like, that's it, that's the vibe check, and you failed it π
okay so sd_bus_message_readv() is literally equivalent to sd_bus_message_read(), except it's called with a va_list instead of a variable number of arguments. And bestie, important caveat: this function does not call the va_end() macro. Because it invokes the va_arg() macro, the value of ap is undefined after the call. no cap, that's just the rule. π
sd_bus_message_peek_type() determines the type of the next element in m to be read by sd_bus_message_read() or similar functions. On success, the type is stored in type, if it is not NULL. If the type is a container type, the type of its elements is stored in contents, if it is not NULL. If this function successfully determines the type of the next element in m, it returns a positive integer. If there are no more elements to be read, it returns zero. peek type, peek slay β¨
π RETURN VALUE π
On success, these functions return a non-negative integer. On failure, they return a negative errno-style error code. that's the vibe check, fr fr π
π Errors π
Returned errors may indicate the following problems, bestie:
-EINVALβ specified type string is invalid, or themessageparameter isNULL. π«-ENXIOβ the message does not contain the specified type at the current position. ngl, awkward.-EBADMSGβ the message cannot be parsed. yikes π-EBUSYβ when reading from a container, this error will be returned if unread elements are left in the container.
Added in version 251.
π§ NOTES π§
Functions described here are available as a shared library, which can be compiled against and linked to with the libsystemd pkg-config(1) file. iconic build behavior β¨
All functions listed here are thread-agnostic and only a single thread may operate on a given object at any given time. Different threads may access the same object at different times. Multiple independent objects may be used from different threads in parallel. so like, share the object, don't fight over it π
The code described here uses getenv(3), which is declared to be not multi-thread-safe. This means that the code calling the functions described here must not call setenv(3) from a parallel thread. It is recommended to only do calls to setenv() from an early phase of the program when no other threads have been started. do the setup early, bestie, before the group chat gets chaotic πΈ
π₯ EXAMPLES π₯
Read a single basic type (a 64-bit integer):
sd_bus_message *m;
int64_t x;
sd_bus_message_read(m, "x", &x);
Read a boolean value:
sd_bus_message *m;
int x; /* Do not use C99 "bool" type here, it is typically smaller
in memory and would cause memory corruption */
sd_bus_message_read(m, "b", &x);
bestie, that comment is not a joke: do not use C99 "bool" here, it is typically smaller in memory and would cause memory corruption. π
Read all types of integers:
uint8_t y;
int16_t n;
uint16_t q;
int32_t i;
uint32_t u;
int64_t x;
uint64_t t;
double d;
sd_bus_message_read(m, "ynqiuxtd", &y, &n, &q, &i, &u, &x, &t, &d);
Read a structure composed of a string and a D-Bus path:
const char *s, *p;
sd_bus_message_read(m, "(so)", &s, &p);
Read a variant, with the real type "gt" (signature, unsigned integer):
const char *s;
uint64_t *v;
sd_bus_message_read(m, "v", "gt", &s, &v);
Read a dictionary containing three pairs of type {integer=>string}:
int i, j, k;
const char *s, *t, *u;
sd_bus_message_read(m, "a{is}", 3, &i, &s, &j, &t, &k, &u);
Read a single file descriptor, and duplicate it in order to keep it open after the message is freed.
sd_bus_message *m;
int fd, fd_copy;
sd_bus_message_read(m, "h", &fd);
fd_copy = fcntl(fd, FD_DUPFD_CLOEXEC, 3);
π¦ HISTORY π¦
sd_bus_message_read() and sd_bus_message_readv() were added in version 240. π
sd_bus_message_peek_type() was added in version 246. β¨
π SEE ALSO π
systemd(1)sd-bus(3)sd_bus_message_read_basic(3)sd_bus_message_skip(3)sd_bus_message_append(3)sd_bus_message_enter_container(3)
okay bye bestie! source/version: systemd 261.3; page: SD_BUS_MESSAGE_READ(3); date: whenever you're reading this in your terminal πΈπ not copying the footer line, just giving it main character energy β¨
π¦ 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