]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
varlink: add new call varlink_connect_fd_pair() helper for two-fd clients
authorLennart Poettering <lennart@poettering.net>
Wed, 24 Apr 2024 19:41:10 +0000 (21:41 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 27 Jun 2024 07:41:54 +0000 (09:41 +0200)
This makes use of the functionality added in the previous commit to
implement the client-side functionality for talking to servers via a
pair of fds.

src/shared/varlink.c
src/shared/varlink.h

index 3dec6dbfa7c5612fc52c19e93ab3dcbfecbae400..fea330b86de53e72e56c4ded11354ba16c10a97e 100644 (file)
@@ -652,23 +652,37 @@ int varlink_connect_url(Varlink **ret, const char *url) {
         return varlink_connect_address(ret, c ?: p);
 }
 
-int varlink_connect_fd(Varlink **ret, int fd) {
+int varlink_connect_fd_pair(Varlink **ret, int input_fd, int output_fd, const struct ucred *override_ucred) {
         Varlink *v;
         int r;
 
         assert_return(ret, -EINVAL);
-        assert_return(fd >= 0, -EBADF);
+        assert_return(input_fd >= 0, -EBADF);
+        assert_return(output_fd >= 0, -EBADF);
 
-        r = fd_nonblock(fd, true);
+        r = fd_nonblock(input_fd, true);
         if (r < 0)
-                return log_debug_errno(r, "Failed to make fd %d nonblocking: %m", fd);
+                return log_debug_errno(r, "Failed to make input fd %d nonblocking: %m", input_fd);
+
+        if (input_fd != output_fd) {
+                r = fd_nonblock(output_fd, true);
+                if (r < 0)
+                        return log_debug_errno(r, "Failed to make output fd %d nonblocking: %m", output_fd);
+        }
 
         r = varlink_new(&v);
         if (r < 0)
                 return log_debug_errno(r, "Failed to create varlink object: %m");
 
-        v->output_fd = v->input_fd = fd;
-        v->af = -1,
+        v->input_fd = input_fd;
+        v->output_fd = output_fd;
+        v->af = -1;
+
+        if (override_ucred) {
+                v->ucred = *override_ucred;
+                v->ucred_acquired = true;
+        }
+
         varlink_set_state(v, VARLINK_IDLE_CLIENT);
 
         /* Note that if this function is called we assume the passed socket (if it is one) is already
@@ -682,6 +696,10 @@ int varlink_connect_fd(Varlink **ret, int fd) {
         return 0;
 }
 
+int varlink_connect_fd(Varlink **ret, int fd) {
+        return varlink_connect_fd_pair(ret, fd, fd, /* override_ucred= */ NULL);
+}
+
 static void varlink_detach_event_sources(Varlink *v) {
         assert(v);
 
index 40a8fd086f61672b170463dc71407d51a8c233da..1ae65424b1e6811b8d4c74ef91bdbe6dc87ec364 100644 (file)
@@ -1,6 +1,8 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
+#include <sys/socket.h>
+
 #include "sd-event.h"
 #include "sd-json.h"
 
@@ -61,6 +63,7 @@ int varlink_connect_address(Varlink **ret, const char *address);
 int varlink_connect_exec(Varlink **ret, const char *command, char **argv);
 int varlink_connect_url(Varlink **ret, const char *url);
 int varlink_connect_fd(Varlink **ret, int fd);
+int varlink_connect_fd_pair(Varlink **ret, int input_fd, int output_fd, const struct ucred *override_ucred);
 
 Varlink* varlink_ref(Varlink *link);
 Varlink* varlink_unref(Varlink *v);