SD_JSON_DISPATCH_STRING(3)

πŸ’– SD_JSON_DISPATCH_STRING πŸ’–

okay bestie, buckle up, this is the sd_json_dispatch_string family from the sd_json_dispatch_string section of the systemd manual pages (manual 3, iykyk) β€” a whole girlband of decode-y little helpers whose entire job is: take a JSON variant value, vibe check it, and write the result into the memory you point at. πŸ¦‹


✨ NAME ✨

so the lineup is, in order, no one left out, periodt:

sd_json_dispatch_string, sd_json_dispatch_const_string, sd_json_dispatch_strv, sd_json_dispatch_stdbool, sd_json_dispatch_intbool, sd_json_dispatch_tristate, sd_json_dispatch_variant, sd_json_dispatch_variant_noref, sd_json_dispatch_int64, sd_json_dispatch_int32, sd_json_dispatch_int16, sd_json_dispatch_int8, sd_json_dispatch_uint64, sd_json_dispatch_uint32, sd_json_dispatch_uint16, sd_json_dispatch_uint8, sd_json_dispatch_double, sd_json_dispatch_uid_gid, sd_json_dispatch_id128, sd_json_dispatch_signal, sd_json_dispatch_unsupported β€” all of them decode JSON variant values and write them to the specified memory. πŸ’…


🌸 SYNOPSIS 🌸

first things first, you gotta include the header:

#include <systemd/sd-varlink.h>

and here's every single signature, exactly as they are, do not come for me:

int sd_json_dispatch_string(const char *name, sd_json_variant *variant,
                            sd_dispatch_flags flags, void *userdata);

int sd_json_dispatch_const_string(const char *name,
                                  sd_json_variant *variant,
                                  sd_dispatch_flags flags,
                                  void *userdata);

int sd_json_dispatch_strv(const char *name, sd_json_variant *variant,
                          sd_dispatch_flags flags, void *userdata);

int sd_json_dispatch_stdbool(const char *name, sd_json_variant *variant,
                             sd_dispatch_flags flags, void *userdata);

int sd_json_dispatch_intbool(const char *name, sd_json_variant *variant,
                             sd_dispatch_flags flags, void *userdata);

int sd_json_dispatch_tristate(const char *name,
                              sd_json_variant *variant,
                              sd_dispatch_flags flags, void *userdata);

int sd_json_dispatch_variant(const char *name, sd_json_variant *variant,
                             sd_dispatch_flags flags, void *userdata);

int sd_json_dispatch_variant_noref(const char *name,
                                   sd_json_variant *variant,
                                   sd_dispatch_flags flags,
                                   void *userdata);

int sd_json_dispatch_int64(const char *name, sd_json_variant *variant,
                           sd_dispatch_flags flags, void *userdata);

int sd_json_dispatch_int32(const char *name, sd_json_variant *variant,
                           sd_dispatch_flags flags, void *userdata);

int sd_json_dispatch_int16(const char *name, sd_json_variant *variant,
                           sd_dispatch_flags flags, void *userdata);

int sd_json_dispatch_int8(const char *name, sd_json_variant *variant,
                          sd_dispatch_flags flags, void *userdata);

int sd_json_dispatch_uint64(const char *name, sd_json_variant *variant,
                            sd_dispatch_flags flags, void *userdata);

int sd_json_dispatch_uint32(const char *name, sd_json_variant *variant,
                            sd_dispatch_flags flags, void *userdata);

int sd_json_dispatch_uint16(const char *name, sd_json_variant *variant,
                            sd_dispatch_flags flags, void *userdata);

int sd_json_dispatch_uint8(const char *name, sd_json_variant *variant,
                           sd_dispatch_flags flags, void *userdata);

int sd_json_dispatch_double(const char *name, sd_json_variant *variant,
                            sd_dispatch_flags flags, void *userdata);

int sd_json_dispatch_uid_gid(const char *name, sd_json_variant *variant,
                             sd_dispatch_flags flags, void *userdata);

int sd_json_dispatch_id128(const char *name, sd_json_variant *variant,
                           sd_dispatch_flags flags, void *userdata);

int sd_json_dispatch_signal(const char *name, sd_json_variant *variant,
                            sd_dispatch_flags flags, void *userdata);

int sd_json_dispatch_unsupported(const char *name,
                                 sd_json_variant *variant,
                                 sd_dispatch_flags flags,
                                 void *userdata);

πŸŽ€ DESCRIPTION πŸŽ€

okay so the whole point: these functions are intended for use in the sd_json_dispatch_field structure arrays that sd_json_dispatch(3) and sd_varlink_dispatch(3) accept. They decode the value of the JSON variant object you hand them, and write it to the memory that the userdata pointer is pointing at. The name parameter holds the field name of the value being decoded β€” like, the name it has inside the JSON object it lives in. And for the deets on the flags parameter, go read the sd_json_dispatch() documentation, bestie, it's all there. πŸ“–

⚠️ heads up: all of these functions not only accept the native JSON type they were made for, they also accept null JSON values β€” and in that case they assign an appropriate invalid/unset/null value, whatever fits the type (more on that below, keep reading πŸ’–).

sd_json_dispatch_string() 🧡

decodes a JSON string value and allocates a NUL terminated copy in dynamic memory. Your userdata pointer must point to a pointer to a string β€” that string gets freed if it's non-NULL, and then replaced by the freshly allocated one. If a JSON null value comes through, the existing string gets freed and NULL is assigned. bye bestie πŸ‘‹

sd_json_dispatch_const_string() πŸ“Œ

very similar to sd_json_dispatch_string(), except it does not allocate a string in dynamic memory. Instead it just writes a pointer into the JSON object straight into the indicated memory (or NULL if a JSON null object is passed). Important: that memory stays valid only as long as the indicated variant object is still allocated β€” which can happen via direct reference, or via an indirect one through an object that references the specified variant. And the memory userdata points to on input is not freed before the new value is assigned. no cleanup era, only pointer era ✨

sd_json_dispatch_stdbool() and sd_json_dispatch_intbool() βœ…

these two decode JSON boolean values and write them to the indicated memory. The former expects a variable of the C99 bool type in that memory; the latter expects an int (which will only ever receive the values 0 and 1). And a JSON null value? Treated equivalent to a JSON false. lowkey generous of them.

sd_json_dispatch_tristate() 🎚️

very similar to sd_json_dispatch_intbool(), but it'll assign -1 if a JSON null value is passed. Or, in other words: the integer will have a value > 0, == 0 or < 0 for the cases true, false or invalid/unset/null. three moods, one int πŸ’…

sd_json_dispatch_variant() 🫢

takes an additional reference to the passed JSON object (via sd_json_variant_ref()) and writes the pointer to the indicated memory. No decoding is done. And if the indicated pointer is non-NULL on input, it gets freed (via sd_json_variant_unref()) before the new pointer is written. clean swap, no cap.

sd_json_dispatch_variant_noref() πŸ™ˆ

similar, but it does not take a new reference to the JSON variant object. So the pointer only stays valid as long as the original object stays referenced. And if the indicated pointer is non-NULL on input, it is not freed before the new pointer is written. so like, mind the lifetime, bestie, fr fr.

the integer squad πŸ”’

sd_json_dispatch_int64(), sd_json_dispatch_int32(), sd_json_dispatch_int16(), sd_json_dispatch_int8(), sd_json_dispatch_uint64(), sd_json_dispatch_uint32(), sd_json_dispatch_uint16() and sd_json_dispatch_uint8() all decode a JSON integer value and write it to the indicated memory. The function names tell you the word width and the signedness of the integers being parsed.

if a JSON null value is passed, the unsigned ones assign the maximum value the type takes (i.e. UINT64_MAX, UINT32_MAX ...), and the signed ones assign -1. 🫠

and plot twist: instead of a JSON integer value, these functions also accept JSON strings containing formatted decimal numbers β€” for compatibility, so that integer values which can't be represented in 64bit double precision floating point numbers can still be encoded by other programming languages that encode JSON numerals that way. iconic workaround tbh.

sd_json_dispatch_double() 🌊

decodes a 64bit double precision floating point number. If a JSON null value is passed, it assigns NaN. (not a number, not a problem πŸ’…)

sd_json_dispatch_uid_gid() πŸ‘‘

similar to sd_json_dispatch_uint32(), and meant for decoding 32bit UNIX UID/GID numbers as used on Linux. It will decode a JSON null value as 4294967295 (i.e. (uid_t) -1), and it will refuse the values 65535 and 4294967295 when passed as JSON numerals β€” that's both the 16bit and the 32bit "invalid" UID/GID, because those values have special meaning for various UNIX syscalls, on different OSes and file systems. so don't try it 🚫

sd_json_dispatch_id128() πŸ†”

decodes a 128bit ID formatted as a JSON string. It supports both RFC9562 UUID formatting, and 64 hexadecimal characters without separators, the same way as sd_id128_from_string(3). If a JSON null value is passed, the all-zero ID is assigned. zeros, but make it valid ✨

sd_json_dispatch_signal() πŸ“‘

decodes a UNIX process signal specification. It expects either a JSON string containing a signal name such as "SIGINT" or "SIGTERM", or an unsigned JSON integer value with the signal number (in the Linux definition). The indicated memory must point to an int variable to write the signal number to. And if a JSON null value is passed, a negative value will be written to the memory. negative, like my will to debug at 2am 😭

sd_json_dispatch_unsupported() πŸ’€

this one will always fail with the -EINVAL error. that's it. that's the whole job. it said "not my department" and clocked out. 🫑


πŸ’œ RETURN VALUE πŸ’œ

On success, these functions return a non-negative integer. On failure, they return a negative errno-style error code.

πŸ’” Errors

the returned errors may indicate these problems, so let's review:

  • -EINVAL β€” an argument is invalid. 🚩
  • -ENOMEM β€” memory allocation failed. 😭

πŸ¦‹ NOTES πŸ¦‹

the functions described here are available as a shared library, which you can compile against and link to with the libsystemd pkg-config(1) file. πŸ“¦

also, important: the code described here uses getenv(3), which is declared to be not multi-thread-safe. Which means: 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. so do your env stuff early, bestie, no threading chaos πŸ’…


⭐ HISTORY ⭐

sd_json_dispatch_string(), sd_json_dispatch_const_string(), sd_json_dispatch_strv(), sd_json_dispatch_stdbool(), sd_json_dispatch_intbool(), sd_json_dispatch_tristate(), sd_json_dispatch_variant(), sd_json_dispatch_variant_noref(), sd_json_dispatch_int64(), sd_json_dispatch_int32(), sd_json_dispatch_int16(), sd_json_dispatch_int8(), sd_json_dispatch_uint64(), sd_json_dispatch_uint32(), sd_json_dispatch_uint16(), sd_json_dispatch_uint8(), sd_json_dispatch_double(), sd_json_dispatch_uid_gid(), sd_json_dispatch_id128(), sd_json_dispatch_signal(), sd_json_dispatch_unsupported() were all added in version 257. glow-up era. 🌈


🌸 SEE ALSO 🌸

systemd(1), sd-json(3), sd-varlink(3), sd_json_dispatch(3), sd_variant_dispatch(3) β€” go read these next, bestie, they're the whole friend group 🫢


and that's the page, periodt πŸ’… this was systemd 262.1 on the SD_JSON_DISPATCH_STRING(3) page β€” thanks for reading all the way to the bottom, ily, now go dispatch some JSON πŸ’–βœ¨πŸŽ€

πŸ“¦ where this page comes from
  • arch rolling: systemd-libs 262.1-1 Β· LGPL-2.1-or-later AND CC0-1.0 AND GPL-2.0-or-later WITH Linux-syscall-note
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms