summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2024-04-24 21:41:10 +0200
committerLennart Poettering <lennart@poettering.net>2024-06-27 09:41:54 +0200
commit6f24e090068ad68fd5e99483cdb760cde4ac6ed2 (patch)
tree9abe5e7cb7e977c1b982e76e3ccc56afe1f65630
parentvarlink: support varlink communication via distinct input/output fds (diff)
downloadsystemd-6f24e090068ad68fd5e99483cdb760cde4ac6ed2.tar.xz
systemd-6f24e090068ad68fd5e99483cdb760cde4ac6ed2.zip
varlink: add new call varlink_connect_fd_pair() helper for two-fd clients
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.
-rw-r--r--src/shared/varlink.c30
-rw-r--r--src/shared/varlink.h3
2 files changed, 27 insertions, 6 deletions
diff --git a/src/shared/varlink.c b/src/shared/varlink.c
index 3dec6dbfa7..fea330b86d 100644
--- a/src/shared/varlink.c
+++ b/src/shared/varlink.c
@@ -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);
diff --git a/src/shared/varlink.h b/src/shared/varlink.h
index 40a8fd086f..1ae65424b1 100644
--- a/src/shared/varlink.h
+++ b/src/shared/varlink.h
@@ -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);