varlink: add varlink_server_listen_auto() helper

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.
This commit is contained in:
Lennart Poettering
2023-09-25 15:51:26 +02:00
parent 4772334013
commit 206504a594
2 changed files with 46 additions and 0 deletions

View 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;

View 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 */