SD_VARLIN...ND_UPGRADE(3)
π sd_varlink_call_and_upgrade β bestie's guide to hijacking a connection π
okay so this is the manual page for sd_varlink_call_and_upgrade(3) (plus its two chaotic little siblings), living in the sd_varlink_call_and_upgrade section of the systemd docs. sit down, grab a strawberry π, we're gonna talk about calling a Varlink method and then straight-up taking over the socket. it's giving "borrowed your charger and never gave it back" energy, except it's on purpose and it's a feature.
β¨ NAME β¨
sd_varlink_call_and_upgrade, sd_varlink_call_and_upgradeb, sd_varlink_call_and_upgradebo β invoke a Varlink method and take over the connection for a raw protocol π¦
πΈ SYNOPSIS πΈ
#include <systemd/sd-varlink.h>
int sd_varlink_call_and_upgrade(sd_varlink *link, const char *method,
sd_json_variant *parameters,
sd_json_variant **ret_parameters,
const char **ret_error_id,
int *ret_input_fd, int *ret_output_fd);
int sd_varlink_call_and_upgradeb(sd_varlink *link, const char *method,
sd_json_variant **ret_parameters,
const char **ret_error_id,
int *ret_input_fd, int *ret_output_fd,
...);
int sd_varlink_call_and_upgradebo(sd_varlink *link, const char *method,
sd_json_variant **ret_parameters,
const char **ret_error_id,
int *ret_input_fd, int *ret_output_fd,
...);
π DESCRIPTION π
so these functions are the client side of a Varlink protocol upgrade. they're the counterpart to the server-side sd_varlink_reply_and_upgrade(3) family β you know, the ones holding up the other end of the phone. π
the whole idea: if you issue a method call this way, then after the reply comes back, the connection is allowed to switch from the Varlink protocol to literally any arbitrary, non-Varlink ("raw") protocol spoken over the underlying socket or pipe file descriptors. it's a lot like the "Upgrade:" mechanism in HTTP. glow-up moment for your socket. β¨
sd_varlink_call_and_upgrade() synchronously invokes the method method on the connection link, requesting a protocol upgrade, and then waits for the reply like a good bestie who actually waits for you to finish your sentence. it takes:
- the Varlink connection object,
- the method name,
- a JSON object with the method call parameters (which may be
NULL), - two output pointers for the reply parameters and a possible error identifier,
- and two output pointers for the file descriptors.
the reply parameters returned in ret_parameters and the error identifier returned in ret_error_id are borrowed references β they only stay valid until the connection is closed or unreffed. not yours to keep, bestie. π either of the two may be passed as NULL if you don't need that info.
if the server replies with a regular reply (rather than a Varlink error), the connection gets upgraded: it's disconnected from the Varlink protocol, and ownership of the underlying file descriptors is transferred to you, the caller, via ret_input_fd and ret_output_fd. congrats, you're responsible for eventually closing them with close(2). yes, that's a real responsibility, no cap.
if the server replies with a Varlink error instead, no upgrade happens and no file descriptors are returned. the error identifier is reported in ret_error_id (if it's non-NULL), otherwise a negative errno-style error derived from it gets returned to you. π
the returned file descriptors are switched to blocking mode. quick lore drop:
- for bidirectional sockets, a single underlying file descriptor carries both directions β in that case
ret_input_fdandret_output_fdcome back as two independent (duplicated) descriptors referring to the same socket, so you can close them separately. - for transports backed by a pair of pipes, the two descriptors differ and refer to the distinct read and write ends.
at least one of ret_input_fd or ret_output_fd must be non-NULL. that's not a suggestion, that's the vibe check. π«Ά
sd_varlink_call_and_upgradeb() is similar to sd_varlink_call_and_upgrade(), except instead of expecting a fully constructed sd_json_variant object carrying the method call parameters, that object is constructed on-the-fly from the variadic argument list, in a style identical to sd_json_build(3). β¨
sd_varlink_call_and_upgradebo() is identical to sd_varlink_call_and_upgradeb(), but an enclosing JSON object is added implicitly, so the argument list is expected to consist of object field pairs only, in a style identical to sd_json_buildo(3). this relationship mirrors that of sd_varlink_call(3) and its sd_varlink_callb()/sd_varlink_callbo() variants β like, same family, same energy. π
π RETURN VALUE π
on success, these functions return a positive integer if the connection was upgraded, or zero if the server returned a Varlink error and ret_error_id was set to it. iconic behavior honestly.
on failure, they return a negative errno-style error code. π
π Errors
the returned errors may indicate the following problems:
-EINVALβ an argument is invalid. one of the vibes was off.-ENOTCONNβ the Varlink connection object is not connected. it's giving "left on read."-EPROTOβ a protocol error occurred, for example the server sent unexpected raw protocol data before the upgrade completed. rude.-ENOMEMβ memory allocation failed. brain empty, no thoughts, no bytes. π§
π NOTES π
the functions described here are available as a shared library, which can be compiled against and linked to with the libsystemd pkg-config(1) file. link it, bestie.
the code described here uses getenv(3), which is declared to be not multi-thread-safe. that means any code calling the functions described here must not call setenv(3) from a parallel thread. the recommendation is to only do calls to setenv() from an early phase of the program, when no other threads have been started yet. do it early or don't do it at all. π«‘
β HISTORY β
sd_varlink_call_and_upgrade()was added in version 261.sd_varlink_call_and_upgradeb()andsd_varlink_call_and_upgradebo()were added in version 262.
π SEE ALSO π
systemd(1), sd-varlink(3), sd_varlink_call(3), sd_varlink_reply_and_upgrade(3), sd_json_build(3)
and that's the whole page, babe! π this was the systemd 262.1 era, so if you see systemd 262.1 floating around, that's the version this page came from. go forth, upgrade your connections, close your file descriptors, and stay hydrated. mwah! πβ¨π¦
π¦ 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