]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-bus/test-bus-server.c
analyze: fix typo
[thirdparty/systemd.git] / src / libsystemd / sd-bus / test-bus-server.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
11c4c249 2
11c4c249 3#include <pthread.h>
5cdf13c7 4#include <sys/socket.h>
11c4c249
LP
5
6#include "sd-bus.h"
07630cea 7
5cdf13c7 8#include "bus-error.h"
07630cea 9#include "log.h"
0a970718 10#include "memory-util.h"
6969a671 11#include "string-util.h"
965040d8 12#include "tests.h"
11c4c249
LP
13
14struct context {
15 int fds[2];
16
17 bool client_negotiate_unix_fds;
18 bool server_negotiate_unix_fds;
19
20 bool client_anonymous_auth;
21 bool server_anonymous_auth;
22};
23
70b16765 24static int _server(struct context *c) {
f7794e42 25 _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
11c4c249
LP
26 sd_id128_t id;
27 bool quit = false;
28 int r;
29
30 assert_se(sd_id128_randomize(&id) >= 0);
31
32 assert_se(sd_bus_new(&bus) >= 0);
e82c9509 33 assert_se(sd_bus_set_fd(bus, c->fds[0], c->fds[0]) >= 0);
11c4c249 34 assert_se(sd_bus_set_server(bus, 1, id) >= 0);
11c4c249 35 assert_se(sd_bus_set_anonymous(bus, c->server_anonymous_auth) >= 0);
264ad849 36 assert_se(sd_bus_negotiate_fds(bus, c->server_negotiate_unix_fds) >= 0);
11c4c249
LP
37 assert_se(sd_bus_start(bus) >= 0);
38
39 while (!quit) {
4afd3348 40 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
11c4c249
LP
41
42 r = sd_bus_process(bus, &m);
70b16765
ZJS
43 if (r < 0)
44 return log_error_errno(r, "Failed to process requests: %m");
11c4c249
LP
45
46 if (r == 0) {
f5fbe71d 47 r = sd_bus_wait(bus, UINT64_MAX);
70b16765
ZJS
48 if (r < 0)
49 return log_error_errno(r, "Failed to wait: %m");
11c4c249
LP
50 continue;
51 }
52
53 if (!m)
54 continue;
55
56 log_info("Got message! member=%s", strna(sd_bus_message_get_member(m)));
57
58 if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "Exit")) {
59
dcd6361e
ZJS
60 assert_se((sd_bus_can_send(bus, 'h') >= 1) ==
61 (c->server_negotiate_unix_fds && c->client_negotiate_unix_fds));
11c4c249 62
df2d202e 63 r = sd_bus_message_new_method_return(m, &reply);
70b16765
ZJS
64 if (r < 0)
65 return log_error_errno(r, "Failed to allocate return: %m");
11c4c249
LP
66
67 quit = true;
68
69 } else if (sd_bus_message_is_method_call(m, NULL, NULL)) {
c784c5ce 70 r = sd_bus_message_new_method_error(
df2d202e 71 m,
151b9b96
LP
72 &reply,
73 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_UNKNOWN_METHOD, "Unknown method."));
70b16765
ZJS
74 if (r < 0)
75 return log_error_errno(r, "Failed to allocate return: %m");
11c4c249
LP
76 }
77
78 if (reply) {
79 r = sd_bus_send(bus, reply, NULL);
70b16765
ZJS
80 if (r < 0)
81 return log_error_errno(r, "Failed to send reply: %m");
11c4c249
LP
82 }
83 }
84
70b16765
ZJS
85 return 0;
86}
11c4c249 87
70b16765
ZJS
88static void* server(void *p) {
89 return INT_TO_PTR(_server(p));
11c4c249
LP
90}
91
92static int client(struct context *c) {
4afd3348
LP
93 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
94 _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
7e284b05 95 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
11c4c249
LP
96 int r;
97
98 assert_se(sd_bus_new(&bus) >= 0);
e82c9509 99 assert_se(sd_bus_set_fd(bus, c->fds[1], c->fds[1]) >= 0);
264ad849 100 assert_se(sd_bus_negotiate_fds(bus, c->client_negotiate_unix_fds) >= 0);
11c4c249
LP
101 assert_se(sd_bus_set_anonymous(bus, c->client_anonymous_auth) >= 0);
102 assert_se(sd_bus_start(bus) >= 0);
103
104 r = sd_bus_message_new_method_call(
105 bus,
151b9b96 106 &m,
11c4c249
LP
107 "org.freedesktop.systemd.test",
108 "/",
109 "org.freedesktop.systemd.test",
151b9b96 110 "Exit");
f647962d
MS
111 if (r < 0)
112 return log_error_errno(r, "Failed to allocate method call: %m");
11c4c249 113
c49b30a2 114 r = sd_bus_call(bus, m, 0, &error, &reply);
4ae25393 115 if (r < 0)
2a03b9ed 116 return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, r));
11c4c249
LP
117
118 return 0;
119}
120
121static int test_one(bool client_negotiate_unix_fds, bool server_negotiate_unix_fds,
122 bool client_anonymous_auth, bool server_anonymous_auth) {
123
124 struct context c;
125 pthread_t s;
126 void *p;
127 int r, q;
128
129 zero(c);
130
131 assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, c.fds) >= 0);
132
133 c.client_negotiate_unix_fds = client_negotiate_unix_fds;
134 c.server_negotiate_unix_fds = server_negotiate_unix_fds;
135 c.client_anonymous_auth = client_anonymous_auth;
136 c.server_anonymous_auth = server_anonymous_auth;
137
138 r = pthread_create(&s, NULL, server, &c);
139 if (r != 0)
140 return -r;
141
142 r = client(&c);
143
144 q = pthread_join(s, &p);
145 if (q != 0)
146 return -q;
147
148 if (r < 0)
149 return r;
150
151 if (PTR_TO_INT(p) < 0)
152 return PTR_TO_INT(p);
153
154 return 0;
155}
156
157int main(int argc, char *argv[]) {
158 int r;
159
965040d8
YW
160 test_setup_logging(LOG_DEBUG);
161
11c4c249
LP
162 r = test_one(true, true, false, false);
163 assert_se(r >= 0);
164
165 r = test_one(true, false, false, false);
166 assert_se(r >= 0);
167
168 r = test_one(false, true, false, false);
169 assert_se(r >= 0);
170
171 r = test_one(false, false, false, false);
172 assert_se(r >= 0);
173
174 r = test_one(true, true, true, true);
175 assert_se(r >= 0);
176
177 r = test_one(true, true, false, true);
178 assert_se(r >= 0);
179
180 r = test_one(true, true, true, false);
181 assert_se(r == -EPERM);
182
183 return EXIT_SUCCESS;
184}