]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
varlink: if varlink_call() is called with ret_error_id=NULL propagate error via retur...
authorLennart Poettering <lennart@poettering.net>
Wed, 17 Jan 2024 09:57:56 +0000 (10:57 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 17 Jan 2024 15:14:10 +0000 (16:14 +0100)
It's OK if callers don't want to know the varlink error string. But in
that case return the fact the call failed via the return value, as a
negative errno as usual, to make sure it's not accidentally ignored.

Similar for varlink_observe()

src/shared/varlink.c

index ce9cf736468099de9f55f5cac14d6b391c9abf96..d39db5382d643f9dd88a4eaecc936ce3510eb7b9 100644 (file)
@@ -2211,21 +2211,29 @@ int varlink_call(
 
         switch (v->state) {
 
-        case VARLINK_CALLED:
+        case VARLINK_CALLED: {
                 assert(v->current);
 
                 varlink_set_state(v, VARLINK_IDLE_CLIENT);
                 assert(v->n_pending == 1);
                 v->n_pending--;
 
+                JsonVariant *e = json_variant_by_key(v->current, "error"),
+                        *p = json_variant_by_key(v->current, "parameters");
+
+                /* If caller doesn't ask for the error string, then let's return an error code in case of failure */
+                if (!ret_error_id && e)
+                        return varlink_error_to_errno(json_variant_string(e), p);
+
                 if (ret_parameters)
-                        *ret_parameters = json_variant_by_key(v->current, "parameters");
+                        *ret_parameters = p;
                 if (ret_error_id)
-                        *ret_error_id = json_variant_string(json_variant_by_key(v->current, "error"));
+                        *ret_error_id = e ? json_variant_string(e) : NULL;
                 if (ret_flags)
                         *ret_flags = 0;
 
                 return 1;
+        }
 
         case VARLINK_PENDING_DISCONNECT:
         case VARLINK_DISCONNECTED:
@@ -2341,6 +2349,11 @@ int varlink_collect(
 
                 /* If we get an error from any of the replies, return immediately with just the error_id and flags*/
                 if (context.error_id) {
+
+                        /* If caller doesn't ask for the error string, then let's return an error code in case of failure */
+                        if (!ret_error_id)
+                                return varlink_error_to_errno(context.error_id, context.parameters);
+
                         if (ret_parameters)
                                 *ret_parameters = TAKE_PTR(context.parameters);
                         if (ret_error_id)
@@ -2374,6 +2387,9 @@ int varlink_collect(
                 assert_not_reached();
         }
 
+        if (!ret_error_id && context.error_id)
+                return varlink_error_to_errno(context.error_id, context.parameters);
+
         if (ret_parameters)
                 *ret_parameters = TAKE_PTR(context.parameters);
         if (ret_error_id)