]> git.proxmox.com Git - systemd.git/blame - src/libsystemd/sd-bus/test-bus-server.c
New upstream version 236
[systemd.git] / src / libsystemd / sd-bus / test-bus-server.c
CommitLineData
52ad194e 1/* SPDX-License-Identifier: LGPL-2.1+ */
663996b3
MS
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
663996b3 21#include <pthread.h>
db2df898 22#include <stdlib.h>
663996b3
MS
23
24#include "sd-bus.h"
db2df898 25
663996b3 26#include "bus-internal.h"
60f067b4 27#include "bus-util.h"
db2df898
MP
28#include "log.h"
29#include "macro.h"
30#include "util.h"
663996b3
MS
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);
52 assert_se(sd_bus_set_fd(bus, c->fds[0], c->fds[0]) >= 0);
53 assert_se(sd_bus_set_server(bus, 1, id) >= 0);
663996b3 54 assert_se(sd_bus_set_anonymous(bus, c->server_anonymous_auth) >= 0);
14228c0d 55 assert_se(sd_bus_negotiate_fds(bus, c->server_negotiate_unix_fds) >= 0);
663996b3
MS
56 assert_se(sd_bus_start(bus) >= 0);
57
58 while (!quit) {
4c89c718 59 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
663996b3
MS
60
61 r = sd_bus_process(bus, &m);
62 if (r < 0) {
f47781d8 63 log_error_errno(r, "Failed to process requests: %m");
663996b3
MS
64 goto fail;
65 }
66
67 if (r == 0) {
68 r = sd_bus_wait(bus, (uint64_t) -1);
69 if (r < 0) {
f47781d8 70 log_error_errno(r, "Failed to wait: %m");
663996b3
MS
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
60f067b4 86 r = sd_bus_message_new_method_return(m, &reply);
663996b3 87 if (r < 0) {
f47781d8 88 log_error_errno(r, "Failed to allocate return: %m");
663996b3
MS
89 goto fail;
90 }
91
92 quit = true;
93
94 } else if (sd_bus_message_is_method_call(m, NULL, NULL)) {
95 r = sd_bus_message_new_method_error(
60f067b4
JS
96 m,
97 &reply,
98 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_UNKNOWN_METHOD, "Unknown method."));
663996b3 99 if (r < 0) {
f47781d8 100 log_error_errno(r, "Failed to allocate return: %m");
663996b3
MS
101 goto fail;
102 }
103 }
104
105 if (reply) {
106 r = sd_bus_send(bus, reply, NULL);
107 if (r < 0) {
f47781d8 108 log_error_errno(r, "Failed to send reply: %m");
663996b3
MS
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) {
4c89c718
MP
126 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
127 _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
663996b3
MS
128 sd_bus_error error = SD_BUS_ERROR_NULL;
129 int r;
130
131 assert_se(sd_bus_new(&bus) >= 0);
132 assert_se(sd_bus_set_fd(bus, c->fds[1], c->fds[1]) >= 0);
14228c0d 133 assert_se(sd_bus_negotiate_fds(bus, c->client_negotiate_unix_fds) >= 0);
663996b3
MS
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,
60f067b4 139 &m,
663996b3
MS
140 "org.freedesktop.systemd.test",
141 "/",
142 "org.freedesktop.systemd.test",
60f067b4 143 "Exit");
f47781d8
MP
144 if (r < 0)
145 return log_error_errno(r, "Failed to allocate method call: %m");
663996b3 146
60f067b4 147 r = sd_bus_call(bus, m, 0, &error, &reply);
663996b3
MS
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}