Coverage Report

Created: 2026-04-29 07:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/systemd/src/shared/varlink-serialize.c
Line
Count
Source
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3
#include "alloc-util.h"
4
#include "extract-word.h"
5
#include "fd-util.h"
6
#include "fdset.h"
7
#include "log.h"
8
#include "serialize.h"
9
#include "socket-util.h"
10
#include "string-util.h"
11
#include "varlink-internal.h"
12
#include "varlink-serialize.h"
13
14
76.3k
int varlink_server_serialize(sd_varlink_server *s, const char *name, FILE *f, FDSet *fds) {
15
76.3k
        assert(f);
16
76.3k
        assert(fds);
17
18
76.3k
        if (!s)
19
76.0k
                return 0;
20
21
292
        const char *prefix = name ? strjoina("varlink-server-", name) : "varlink-server";
22
23
292
        LIST_FOREACH(sockets, ss, s->sockets) {
24
0
                assert(ss->address);
25
0
                assert(ss->fd >= 0);
26
27
                /* If we fail to serialize the fd, it will be considered an error during deserialization */
28
0
                int copy = fdset_put_dup(fds, ss->fd);
29
0
                if (copy < 0)
30
0
                        return copy;
31
32
0
                fprintf(f, "%s-socket-address=%s varlink-server-socket-fd=%d\n", prefix, ss->address, copy);
33
0
        }
34
35
292
        return 0;
36
292
}
37
38
2.47k
int varlink_server_deserialize_one(sd_varlink_server *s, const char *value, FDSet *fds) {
39
2.47k
        _cleanup_free_ char *address = NULL;
40
2.47k
        _cleanup_close_ int fd = -EBADF;
41
2.47k
        const char *v;
42
2.47k
        int r;
43
44
        /* This function expects a serialization line with "varlink-server(-name)-" prefix stripped! */
45
46
2.47k
        assert(s);
47
2.47k
        assert(value);
48
2.47k
        assert(fds);
49
50
2.47k
        v = startswith(value, "socket-address=");
51
2.47k
        if (!v)
52
2.47k
                return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
53
1.70k
                                       "Invalid varlink server serialization entry: %s", value);
54
55
1.70k
        r = extract_first_word(&v, &address, " ", /* flags = */ 0);
56
1.70k
        if (r <= 0)
57
1.70k
                return varlink_server_log_errno(s, r < 0 ? r : SYNTHETIC_ERRNO(ENODATA),
58
1.12k
                                                "Failed to extract socket address from varlink serialization: %s", value);
59
1.12k
        if (v)
60
599
                v = startswith(v, "varlink-server-socket-fd=");
61
1.12k
        if (!v)
62
1.12k
                return varlink_server_log_errno(s, SYNTHETIC_ERRNO(EBADF),
63
391
                                                "Got varlink serialization without socket fd, refusing.");
64
65
391
        fd = deserialize_fd(fds, v);
66
391
        if (fd < 0)
67
391
                return varlink_server_log_errno(s, fd, "Failed to deserialize varlink socket fd: %m");
68
69
        /* NB: varlink_server_socket_free() does not close the fd! */
70
0
        _cleanup_(varlink_server_socket_freep) VarlinkServerSocket *ss = NULL;
71
0
        ss = new(VarlinkServerSocket, 1);
72
0
        if (!ss)
73
0
                return log_oom_debug();
74
75
0
        *ss = (VarlinkServerSocket) {
76
0
                .server = s,
77
0
                .address = TAKE_PTR(address),
78
0
                .fd = fd,
79
0
        };
80
81
0
        r = varlink_server_add_socket_event_source(s, ss);
82
0
        if (r < 0)
83
0
                return varlink_server_log_errno(s, r, "Failed to add VarlinkServerSocket event source to the event loop: %m");
84
85
0
        LIST_PREPEND(sockets, s->sockets, TAKE_PTR(ss));
86
0
        TAKE_FD(fd); /* ownership is now transferred to varlink server */
87
88
0
        return 0;
89
0
}
90
91
0
bool varlink_server_contains_socket(sd_varlink_server *s, const char *address) {
92
0
        int r;
93
94
0
        assert(s);
95
0
        assert(address);
96
97
0
        LIST_FOREACH(sockets, ss, s->sockets) {
98
0
                r = socket_address_equal_unix(ss->address, address);
99
0
                if (r < 0)
100
0
                        log_debug_errno(r, "Failed to compare '%s' and '%s', ignoring: %m", ss->address, address);
101
0
                if (r > 0)
102
0
                        return true;
103
0
        }
104
105
0
        return false;
106
0
}