]> git.ipfire.org Git - thirdparty/systemd.git/blame_incremental - src/libsystemd/sd-bus/test-bus-server.c
ukify: fix parsing uname version with '+'
[thirdparty/systemd.git] / src / libsystemd / sd-bus / test-bus-server.c
... / ...
CommitLineData
1/* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3#include <pthread.h>
4#include <sys/socket.h>
5
6#include "sd-bus.h"
7
8#include "bus-error.h"
9#include "log.h"
10#include "memory-util.h"
11#include "string-util.h"
12#include "tests.h"
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
24static int _server(struct context *c) {
25 _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
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);
33 assert_se(sd_bus_set_fd(bus, c->fds[0], c->fds[0]) >= 0);
34 assert_se(sd_bus_set_server(bus, 1, id) >= 0);
35 assert_se(sd_bus_set_anonymous(bus, c->server_anonymous_auth) >= 0);
36 assert_se(sd_bus_negotiate_fds(bus, c->server_negotiate_unix_fds) >= 0);
37 assert_se(sd_bus_start(bus) >= 0);
38
39 while (!quit) {
40 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
41
42 r = sd_bus_process(bus, &m);
43 if (r < 0)
44 return log_error_errno(r, "Failed to process requests: %m");
45
46 if (r == 0) {
47 r = sd_bus_wait(bus, UINT64_MAX);
48 if (r < 0)
49 return log_error_errno(r, "Failed to wait: %m");
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
60 assert_se((sd_bus_can_send(bus, 'h') >= 1) ==
61 (c->server_negotiate_unix_fds && c->client_negotiate_unix_fds));
62
63 r = sd_bus_message_new_method_return(m, &reply);
64 if (r < 0)
65 return log_error_errno(r, "Failed to allocate return: %m");
66
67 quit = true;
68
69 } else if (sd_bus_message_is_method_call(m, NULL, NULL)) {
70 r = sd_bus_message_new_method_error(
71 m,
72 &reply,
73 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_UNKNOWN_METHOD, "Unknown method."));
74 if (r < 0)
75 return log_error_errno(r, "Failed to allocate return: %m");
76 }
77
78 if (reply) {
79 r = sd_bus_send(bus, reply, NULL);
80 if (r < 0)
81 return log_error_errno(r, "Failed to send reply: %m");
82 }
83 }
84
85 return 0;
86}
87
88static void* server(void *p) {
89 return INT_TO_PTR(_server(p));
90}
91
92static int client(struct context *c) {
93 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
94 _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
95 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
96 int r;
97
98 assert_se(sd_bus_new(&bus) >= 0);
99 assert_se(sd_bus_set_fd(bus, c->fds[1], c->fds[1]) >= 0);
100 assert_se(sd_bus_negotiate_fds(bus, c->client_negotiate_unix_fds) >= 0);
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,
106 &m,
107 "org.freedesktop.systemd.test",
108 "/",
109 "org.freedesktop.systemd.test",
110 "Exit");
111 if (r < 0)
112 return log_error_errno(r, "Failed to allocate method call: %m");
113
114 r = sd_bus_call(bus, m, 0, &error, &reply);
115 if (r < 0)
116 return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, r));
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
160 test_setup_logging(LOG_DEBUG);
161
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}