]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-bus/test-bus-server.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / libsystemd / sd-bus / test-bus-server.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
11c4c249
LP
2/***
3 This file is part of systemd.
4
5 Copyright 2013 Lennart Poettering
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19***/
20
11c4c249 21#include <pthread.h>
07630cea 22#include <stdlib.h>
11c4c249
LP
23
24#include "sd-bus.h"
07630cea 25
11c4c249 26#include "bus-internal.h"
057171ef 27#include "bus-util.h"
07630cea
LP
28#include "log.h"
29#include "macro.h"
30#include "util.h"
11c4c249
LP
31
32struct context {
33 int fds[2];
34
35 bool client_negotiate_unix_fds;
36 bool server_negotiate_unix_fds;
37
38 bool client_anonymous_auth;
39 bool server_anonymous_auth;
40};
41
42static void *server(void *p) {
43 struct context *c = p;
44 sd_bus *bus = NULL;
45 sd_id128_t id;
46 bool quit = false;
47 int r;
48
49 assert_se(sd_id128_randomize(&id) >= 0);
50
51 assert_se(sd_bus_new(&bus) >= 0);
e82c9509 52 assert_se(sd_bus_set_fd(bus, c->fds[0], c->fds[0]) >= 0);
11c4c249 53 assert_se(sd_bus_set_server(bus, 1, id) >= 0);
11c4c249 54 assert_se(sd_bus_set_anonymous(bus, c->server_anonymous_auth) >= 0);
264ad849 55 assert_se(sd_bus_negotiate_fds(bus, c->server_negotiate_unix_fds) >= 0);
11c4c249
LP
56 assert_se(sd_bus_start(bus) >= 0);
57
58 while (!quit) {
4afd3348 59 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
11c4c249
LP
60
61 r = sd_bus_process(bus, &m);
62 if (r < 0) {
da927ba9 63 log_error_errno(r, "Failed to process requests: %m");
11c4c249
LP
64 goto fail;
65 }
66
67 if (r == 0) {
68 r = sd_bus_wait(bus, (uint64_t) -1);
69 if (r < 0) {
da927ba9 70 log_error_errno(r, "Failed to wait: %m");
11c4c249
LP
71 goto fail;
72 }
73
74 continue;
75 }
76
77 if (!m)
78 continue;
79
80 log_info("Got message! member=%s", strna(sd_bus_message_get_member(m)));
81
82 if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "Exit")) {
83
84 assert_se((sd_bus_can_send(bus, 'h') >= 1) == (c->server_negotiate_unix_fds && c->client_negotiate_unix_fds));
85
df2d202e 86 r = sd_bus_message_new_method_return(m, &reply);
11c4c249 87 if (r < 0) {
da927ba9 88 log_error_errno(r, "Failed to allocate return: %m");
11c4c249
LP
89 goto fail;
90 }
91
92 quit = true;
93
94 } else if (sd_bus_message_is_method_call(m, NULL, NULL)) {
c784c5ce 95 r = sd_bus_message_new_method_error(
df2d202e 96 m,
151b9b96
LP
97 &reply,
98 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_UNKNOWN_METHOD, "Unknown method."));
11c4c249 99 if (r < 0) {
da927ba9 100 log_error_errno(r, "Failed to allocate return: %m");
11c4c249
LP
101 goto fail;
102 }
103 }
104
105 if (reply) {
106 r = sd_bus_send(bus, reply, NULL);
107 if (r < 0) {
da927ba9 108 log_error_errno(r, "Failed to send reply: %m");
11c4c249
LP
109 goto fail;
110 }
111 }
112 }
113
114 r = 0;
115
116fail:
117 if (bus) {
118 sd_bus_flush(bus);
119 sd_bus_unref(bus);
120 }
121
122 return INT_TO_PTR(r);
123}
124
125static int client(struct context *c) {
4afd3348
LP
126 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
127 _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
c784c5ce 128 sd_bus_error error = SD_BUS_ERROR_NULL;
11c4c249
LP
129 int r;
130
131 assert_se(sd_bus_new(&bus) >= 0);
e82c9509 132 assert_se(sd_bus_set_fd(bus, c->fds[1], c->fds[1]) >= 0);
264ad849 133 assert_se(sd_bus_negotiate_fds(bus, c->client_negotiate_unix_fds) >= 0);
11c4c249
LP
134 assert_se(sd_bus_set_anonymous(bus, c->client_anonymous_auth) >= 0);
135 assert_se(sd_bus_start(bus) >= 0);
136
137 r = sd_bus_message_new_method_call(
138 bus,
151b9b96 139 &m,
11c4c249
LP
140 "org.freedesktop.systemd.test",
141 "/",
142 "org.freedesktop.systemd.test",
151b9b96 143 "Exit");
f647962d
MS
144 if (r < 0)
145 return log_error_errno(r, "Failed to allocate method call: %m");
11c4c249 146
c49b30a2 147 r = sd_bus_call(bus, m, 0, &error, &reply);
11c4c249
LP
148 if (r < 0) {
149 log_error("Failed to issue method call: %s", bus_error_message(&error, -r));
150 return r;
151 }
152
153 return 0;
154}
155
156static int test_one(bool client_negotiate_unix_fds, bool server_negotiate_unix_fds,
157 bool client_anonymous_auth, bool server_anonymous_auth) {
158
159 struct context c;
160 pthread_t s;
161 void *p;
162 int r, q;
163
164 zero(c);
165
166 assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, c.fds) >= 0);
167
168 c.client_negotiate_unix_fds = client_negotiate_unix_fds;
169 c.server_negotiate_unix_fds = server_negotiate_unix_fds;
170 c.client_anonymous_auth = client_anonymous_auth;
171 c.server_anonymous_auth = server_anonymous_auth;
172
173 r = pthread_create(&s, NULL, server, &c);
174 if (r != 0)
175 return -r;
176
177 r = client(&c);
178
179 q = pthread_join(s, &p);
180 if (q != 0)
181 return -q;
182
183 if (r < 0)
184 return r;
185
186 if (PTR_TO_INT(p) < 0)
187 return PTR_TO_INT(p);
188
189 return 0;
190}
191
192int main(int argc, char *argv[]) {
193 int r;
194
195 r = test_one(true, true, false, false);
196 assert_se(r >= 0);
197
198 r = test_one(true, false, false, false);
199 assert_se(r >= 0);
200
201 r = test_one(false, true, false, false);
202 assert_se(r >= 0);
203
204 r = test_one(false, false, false, false);
205 assert_se(r >= 0);
206
207 r = test_one(true, true, true, true);
208 assert_se(r >= 0);
209
210 r = test_one(true, true, false, true);
211 assert_se(r >= 0);
212
213 r = test_one(true, true, true, false);
214 assert_se(r == -EPERM);
215
216 return EXIT_SUCCESS;
217}