summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2024-05-11 13:50:26 +0200
committerLuca Boccassi <luca.boccassi@gmail.com>2024-05-22 22:08:28 +0200
commitf5faf4ec5b2523d964565b7b8bcc79a2fb4cf3fc (patch)
tree14b23cf7954ab9d9cdb445646ba4e9b2ab3d6220
parentsd-ndisc: do not print "(null)" in the log message (diff)
downloadsystemd-f5faf4ec5b2523d964565b7b8bcc79a2fb4cf3fc.tar.xz
systemd-f5faf4ec5b2523d964565b7b8bcc79a2fb4cf3fc.zip
varlinkctl: when operating in --more mode, fail correcly on Varlink method error
In varlink.c we generally do not make failing callback functions fatal, since that should be up to the app. Hence, in case of varlinkctl (where we want failures to be fatal), make sure to propagate the error back explicitly. Before this change a failing call to "varlinkctl --more call …" would result in a zero exit code. With this it will correctly exit with a non-zero exit code.
-rw-r--r--src/varlinkctl/varlinkctl.c9
-rwxr-xr-xtest/units/TEST-74-AUX-UTILS.varlinkctl.sh5
2 files changed, 9 insertions, 5 deletions
diff --git a/src/varlinkctl/varlinkctl.c b/src/varlinkctl/varlinkctl.c
index 26b764aca6..9da484d3b8 100644
--- a/src/varlinkctl/varlinkctl.c
+++ b/src/varlinkctl/varlinkctl.c
@@ -350,7 +350,7 @@ static int reply_callback(
VarlinkReplyFlags flags,
void *userdata) {
- int r;
+ int *ret = ASSERT_PTR(userdata), r;
assert(link);
@@ -358,7 +358,7 @@ static int reply_callback(
/* Propagate the error we received via sd_notify() */
(void) sd_notifyf(/* unset_environment= */ false, "VARLINKERROR=%s", error);
- r = log_error_errno(SYNTHETIC_ERRNO(EBADE), "Method call failed: %s", error);
+ r = *ret = log_error_errno(SYNTHETIC_ERRNO(EBADE), "Method call failed: %s", error);
} else
r = 0;
@@ -432,7 +432,8 @@ static int verb_call(int argc, char *argv[], void *userdata) {
} else if (arg_method_flags & VARLINK_METHOD_MORE) {
- varlink_set_userdata(vl, (void*) method);
+ int ret = 0;
+ varlink_set_userdata(vl, &ret);
r = varlink_bind_reply(vl, reply_callback);
if (r < 0)
@@ -459,6 +460,8 @@ static int verb_call(int argc, char *argv[], void *userdata) {
if (r < 0)
return log_error_errno(r, "Failed to wait for varlink connection events: %m");
}
+
+ return ret;
} else {
JsonVariant *reply = NULL;
const char *error = NULL;
diff --git a/test/units/TEST-74-AUX-UTILS.varlinkctl.sh b/test/units/TEST-74-AUX-UTILS.varlinkctl.sh
index 7912360315..1d5a98b214 100755
--- a/test/units/TEST-74-AUX-UTILS.varlinkctl.sh
+++ b/test/units/TEST-74-AUX-UTILS.varlinkctl.sh
@@ -32,8 +32,9 @@ if command -v userdbctl >/dev/null; then
systemctl start systemd-userdbd
varlinkctl call /run/systemd/userdb/io.systemd.Multiplexer io.systemd.UserDatabase.GetUserRecord '{ "userName" : "testuser", "service" : "io.systemd.Multiplexer" }'
varlinkctl call -j /run/systemd/userdb/io.systemd.Multiplexer io.systemd.UserDatabase.GetUserRecord '{ "userName" : "testuser", "service" : "io.systemd.Multiplexer" }' | jq .
- varlinkctl call --more /run/systemd/userdb/io.systemd.Multiplexer io.systemd.UserDatabase.GetMemberships '{ "service" : "io.systemd.Multiplexer" }'
- varlinkctl call --more -j /run/systemd/userdb/io.systemd.Multiplexer io.systemd.UserDatabase.GetMemberships '{ "service" : "io.systemd.Multiplexer" }' | jq --seq .
+ # We ignore the return value of the following two calls, since if no memberships are defined at all this will return a NotFound error, which is OK
+ (varlinkctl call --more /run/systemd/userdb/io.systemd.Multiplexer io.systemd.UserDatabase.GetMemberships '{ "service" : "io.systemd.Multiplexer" }' ||:)
+ (varlinkctl call --more -j /run/systemd/userdb/io.systemd.Multiplexer io.systemd.UserDatabase.GetMemberships '{ "service" : "io.systemd.Multiplexer" }' ||:) | jq --seq .
varlinkctl call --oneway /run/systemd/userdb/io.systemd.Multiplexer io.systemd.UserDatabase.GetMemberships '{ "service" : "io.systemd.Multiplexer" }'
(! varlinkctl call --oneway /run/systemd/userdb/io.systemd.Multiplexer io.systemd.UserDatabase.GetMemberships '{ "service" : "io.systemd.Multiplexer" }' | grep .)
fi