1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
31 #include "bus-message.h"
32 #include "bus-error.h"
34 static int server_init(sd_bus **_bus) {
40 r = sd_bus_open_user(&bus);
42 log_error("Failed to connect to user bus: %s", strerror(-r));
46 r = sd_bus_request_name(bus, "org.freedesktop.systemd.test", 0);
48 log_error("Failed to acquire name: %s", strerror(-r));
62 static int server(sd_bus *bus) {
64 bool client1_gone = false, client2_gone = false;
66 while (!client1_gone || !client2_gone) {
67 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
69 r = sd_bus_process(bus, &m);
71 log_error("Failed to process requests: %s", strerror(-r));
76 r = sd_bus_wait(bus, (uint64_t) -1);
78 log_error("Failed to wait: %s", strerror(-r));
88 log_info("Got message! %s", strna(sd_bus_message_get_member(m)));
89 /* bus_message_dump(m); */
90 /* sd_bus_message_rewind(m, true); */
92 if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "LowerCase")) {
94 _cleanup_free_ char *lowercase = NULL;
96 r = sd_bus_message_read(m, "s", &hello);
98 log_error("Failed to get parameter: %s", strerror(-r));
102 r = sd_bus_message_new_method_return(bus, m, &reply);
104 log_error("Failed to allocate return: %s", strerror(-r));
108 lowercase = strdup(hello);
114 ascii_strlower(lowercase);
116 r = sd_bus_message_append(reply, "s", lowercase);
118 log_error("Failed to append message: %s", strerror(-r));
121 } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "ExitClient1")) {
123 r = sd_bus_message_new_method_return(bus, m, &reply);
125 log_error("Failed to allocate return: %s", strerror(-r));
130 } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "ExitClient2")) {
132 r = sd_bus_message_new_method_return(bus, m, &reply);
134 log_error("Failed to allocate return: %s", strerror(-r));
139 } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "Slow")) {
141 r = sd_bus_message_new_method_return(bus, m, &reply);
143 log_error("Failed to allocate return: %s", strerror(-r));
148 } else if (sd_bus_message_is_method_call(m, NULL, NULL)) {
149 const sd_bus_error e = SD_BUS_ERROR_INIT_CONST("org.freedesktop.DBus.Error.UnknownMethod", "Unknown method.");
151 r = sd_bus_message_new_method_error(bus, m, &e, &reply);
153 log_error("Failed to allocate return: %s", strerror(-r));
159 r = sd_bus_send(bus, reply, NULL);
161 log_error("Failed to send reply: %s", strerror(-r));
165 /* log_info("Sent"); */
166 /* bus_message_dump(reply); */
167 /* sd_bus_message_rewind(reply, true); */
182 static void* client1(void*p) {
183 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
185 sd_bus_error error = SD_BUS_ERROR_INIT;
189 r = sd_bus_open_user(&bus);
191 log_error("Failed to connect to user bus: %s", strerror(-r));
195 r = sd_bus_message_new_method_call(
197 "org.freedesktop.systemd.test",
199 "org.freedesktop.systemd.test",
203 log_error("Failed to allocate method call: %s", strerror(-r));
207 r = sd_bus_message_append(m, "s", "HELLO");
209 log_error("Failed to append string: %s", strerror(-r));
213 r = sd_bus_send_with_reply_and_block(bus, m, 0, &error, &reply);
215 log_error("Failed to issue method call: %s", bus_error_message(&error, -r));
219 r = sd_bus_message_read(reply, "s", &hello);
221 log_error("Failed to get string: %s", strerror(-r));
225 assert(streq(hello, "hello"));
231 _cleanup_bus_message_unref_ sd_bus_message *q;
233 r = sd_bus_message_new_method_call(
235 "org.freedesktop.systemd.test",
237 "org.freedesktop.systemd.test",
241 log_error("Failed to allocate method call: %s", strerror(-r));
245 sd_bus_send(bus, q, NULL);
250 sd_bus_error_free(&error);
251 return INT_TO_PTR(r);
254 static int quit_callback(sd_bus *b, int ret, sd_bus_message *m, void *userdata) {
257 log_error("Quit callback: %s", strerror(ret));
263 static void* client2(void*p) {
264 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
266 sd_bus_error error = SD_BUS_ERROR_INIT;
270 r = sd_bus_open_user(&bus);
272 log_error("Failed to connect to user bus: %s", strerror(-r));
276 r = sd_bus_message_new_method_call(
278 "org.freedesktop.systemd.test",
280 "org.freedesktop.systemd.test",
284 log_error("Failed to allocate method call: %s", strerror(-r));
288 r = sd_bus_send_with_reply_and_block(bus, m, 200 * USEC_PER_MSEC, &error, &reply);
290 log_info("Failed to issue method call: %s", bus_error_message(&error, -r));
292 log_info("Slow call succeed.");
294 sd_bus_message_unref(m);
297 r = sd_bus_message_new_method_call(
299 "org.freedesktop.systemd.test",
301 "org.freedesktop.systemd.test",
305 log_error("Failed to allocate method call: %s", strerror(-r));
309 r = sd_bus_send_with_reply(bus, m, quit_callback, &quit, 200 * USEC_PER_MSEC, NULL);
311 log_info("Failed to issue method call: %s", bus_error_message(&error, -r));
316 r = sd_bus_process(bus, NULL);
318 log_error("Failed to process requests: %s", strerror(-r));
322 r = sd_bus_wait(bus, (uint64_t) -1);
324 log_error("Failed to wait: %s", strerror(-r));
334 _cleanup_bus_message_unref_ sd_bus_message *q;
336 r = sd_bus_message_new_method_call(
338 "org.freedesktop.systemd.test",
340 "org.freedesktop.systemd.test",
344 log_error("Failed to allocate method call: %s", strerror(-r));
348 sd_bus_send(bus, q, NULL);
353 sd_bus_error_free(&error);
354 return INT_TO_PTR(r);
357 int main(int argc, char *argv[]) {
363 r = server_init(&bus);
367 log_info("Initialized...");
369 r = pthread_create(&c1, NULL, client1, bus);
373 r = pthread_create(&c2, NULL, client2, bus);
379 q = pthread_join(c1, &p);
382 q = pthread_join(c2, &p);