/* SPDX-License-Identifier: LGPL-2.1-or-later */ #include "parse-util.h" #include "varlink-internal.h" #include "varlink-serialize.h" int varlink_server_serialize(sd_varlink_server *s, FILE *f, FDSet *fds) { assert(f); assert(fds); if (!s) return 0; LIST_FOREACH(sockets, ss, s->sockets) { int copy; assert(ss->address); assert(ss->fd >= 0); fprintf(f, "varlink-server-socket-address=%s", ss->address); /* If we fail to serialize the fd, it will be considered an error during deserialization */ copy = fdset_put_dup(fds, ss->fd); if (copy < 0) return copy; fprintf(f, " varlink-server-socket-fd=%i", copy); fputc('\n', f); } return 0; } int varlink_server_deserialize_one(sd_varlink_server *s, const char *value, FDSet *fds) { _cleanup_(varlink_server_socket_freep) VarlinkServerSocket *ss = NULL; _cleanup_free_ char *address = NULL; const char *v = ASSERT_PTR(value); int r, fd = -EBADF; char *buf; size_t n; assert(s); assert(fds); n = strcspn(v, " "); address = strndup(v, n); if (!address) return log_oom_debug(); if (v[n] != ' ') return varlink_server_log_errno(s, SYNTHETIC_ERRNO(EINVAL), "Failed to deserialize sd_varlink_server_socket: %s: %m", value); v = startswith(v + n + 1, "varlink-server-socket-fd="); if (!v) return varlink_server_log_errno(s, SYNTHETIC_ERRNO(EINVAL), "Failed to deserialize VarlinkServerSocket fd %s: %m", value); n = strcspn(v, " "); buf = strndupa_safe(v, n); fd = parse_fd(buf); if (fd < 0) return varlink_server_log_errno(s, fd, "Unable to parse VarlinkServerSocket varlink-server-socket-fd=%s: %m", buf); if (!fdset_contains(fds, fd)) return varlink_server_log_errno(s, SYNTHETIC_ERRNO(EBADF), "VarlinkServerSocket varlink-server-socket-fd= has unknown fd %d: %m", fd); ss = new(VarlinkServerSocket, 1); if (!ss) return log_oom_debug(); *ss = (VarlinkServerSocket) { .server = s, .address = TAKE_PTR(address), .fd = fdset_remove(fds, fd), }; r = varlink_server_add_socket_event_source(s, ss, SD_EVENT_PRIORITY_NORMAL); if (r < 0) return varlink_server_log_errno(s, r, "Failed to add VarlinkServerSocket event source to the event loop: %m"); LIST_PREPEND(sockets, s->sockets, TAKE_PTR(ss)); return 0; }