]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
varlink: add varlink_server_listen_auto() helper
authorLennart Poettering <lennart@poettering.net>
Mon, 25 Sep 2023 13:51:26 +0000 (15:51 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 6 Oct 2023 09:49:38 +0000 (11:49 +0200)
This new helper will automatically take listening fds passed in from the
service manager and processes varlink on them. It's useful for Varlink
services that shall be socket activatable.

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

index 6015aed4cf039c679f6a873cd604e8a1bc2cfc6c..229d97febf30851e6b14b4014430d3504dc69da5 100644 (file)
@@ -3,6 +3,8 @@
 #include <malloc.h>
 #include <poll.h>
 
+#include <sd-daemon.h>
+
 #include "alloc-util.h"
 #include "errno-util.h"
 #include "fd-util.h"
@@ -3061,6 +3063,49 @@ int varlink_server_listen_address(VarlinkServer *s, const char *address, mode_t
         return 0;
 }
 
+int varlink_server_listen_auto(VarlinkServer *s) {
+        _cleanup_strv_free_ char **names = NULL;
+        int r, n = 0;
+
+        assert_return(s, -EINVAL);
+
+        /* Adds all passed fds marked as "varlink" to our varlink server. These fds can either refer to a
+         * listening socket or to a connection socket.
+         *
+         * See https://varlink.org/#activation for the environment variables this is backed by and the
+         * recommended "varlink" identifier in $LISTEN_FDNAMES. */
+
+        r = sd_listen_fds_with_names(/* unset_environment= */ false, &names);
+        if (r < 0)
+                return r;
+
+        for (int i = 0; i < r; i++) {
+                int b, fd;
+                socklen_t l = sizeof(b);
+
+                if (!streq(names[i], "varlink"))
+                        continue;
+
+                fd = SD_LISTEN_FDS_START + i;
+
+                if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &b, &l) < 0)
+                        return -errno;
+
+                assert(l == sizeof(b));
+
+                if (b) /* Listening socket? */
+                        r = varlink_server_listen_fd(s, fd);
+                else /* Otherwise assume connection socket */
+                        r = varlink_server_add_connection(s, fd, NULL);
+                if (r < 0)
+                        return r;
+
+                n++;
+        }
+
+        return n;
+}
+
 void* varlink_server_set_userdata(VarlinkServer *s, void *userdata) {
         void *ret;
 
index 143d82cabc6066127726071f970630746b1b458a..776904890d8b9c2ea5d530b1110ea846b8ddf205 100644 (file)
@@ -147,6 +147,7 @@ VarlinkServer *varlink_server_unref(VarlinkServer *s);
 /* Add addresses or fds to listen on */
 int varlink_server_listen_address(VarlinkServer *s, const char *address, mode_t mode);
 int varlink_server_listen_fd(VarlinkServer *s, int fd);
+int varlink_server_listen_auto(VarlinkServer *s);
 int varlink_server_add_connection(VarlinkServer *s, int fd, Varlink **ret);
 
 /* Bind callbacks */