]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
varlinkctl: when operating in --more mode, fail correcly on Varlink method error
authorLennart Poettering <lennart@poettering.net>
Sat, 11 May 2024 11:50:26 +0000 (13:50 +0200)
committerLuca Boccassi <luca.boccassi@gmail.com>
Wed, 22 May 2024 20:08:28 +0000 (22:08 +0200)
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.

src/varlinkctl/varlinkctl.c
test/units/TEST-74-AUX-UTILS.varlinkctl.sh

index 26b764aca696e54df60c9f04b512910234beae9b..9da484d3b8889daf3071230926a3b8ebb18bbf8f 100644 (file)
@@ -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;
index 7912360315e97187f266b19365d4e9231b46e452..1d5a98b214b60c8486a3bbbe7b59dd927d10dc17 100755 (executable)
@@ -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