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) {
41 r = sd_bus_open_user(&bus);
43 log_error("Failed to connect to user bus: %s", strerror(-r));
47 r = sd_bus_get_peer(bus, &id);
49 log_error("Failed to get peer ID: %s", strerror(-r));
53 log_info("Peer ID is " SD_ID128_FORMAT_STR ".", SD_ID128_FORMAT_VAL(id));
54 log_info("Can send file handles: %i", sd_bus_can_send(bus, 'h'));
55 log_info("Unique ID: %s", strna(sd_bus_get_unique_name(bus)));
57 r = sd_bus_request_name(bus, "org.freedesktop.systemd.test", 0);
59 log_error("Failed to acquire name: %s", strerror(-r));
73 static int server(sd_bus *bus) {
75 bool client1_gone = false, client2_gone = false;
77 while (!client1_gone || !client2_gone) {
78 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
80 r = sd_bus_process(bus, &m);
82 log_error("Failed to process requests: %s", strerror(-r));
87 r = sd_bus_wait(bus, (uint64_t) -1);
89 log_error("Failed to wait: %s", strerror(-r));
99 log_info("Got message! %s", strna(sd_bus_message_get_member(m)));
100 /* bus_message_dump(m); */
101 /* sd_bus_message_rewind(m, true); */
103 if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "LowerCase")) {
105 _cleanup_free_ char *lowercase = NULL;
107 r = sd_bus_message_read(m, "s", &hello);
109 log_error("Failed to get parameter: %s", strerror(-r));
113 r = sd_bus_message_new_method_return(bus, m, &reply);
115 log_error("Failed to allocate return: %s", strerror(-r));
119 lowercase = strdup(hello);
125 ascii_strlower(lowercase);
127 r = sd_bus_message_append(reply, "s", lowercase);
129 log_error("Failed to append message: %s", strerror(-r));
132 } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "ExitClient1")) {
134 r = sd_bus_message_new_method_return(bus, m, &reply);
136 log_error("Failed to allocate return: %s", strerror(-r));
141 } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "ExitClient2")) {
143 r = sd_bus_message_new_method_return(bus, m, &reply);
145 log_error("Failed to allocate return: %s", strerror(-r));
150 } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "Slow")) {
152 r = sd_bus_message_new_method_return(bus, m, &reply);
154 log_error("Failed to allocate return: %s", strerror(-r));
159 } else if (sd_bus_message_is_method_call(m, NULL, NULL)) {
160 const sd_bus_error e = SD_BUS_ERROR_INIT_CONST("org.freedesktop.DBus.Error.UnknownMethod", "Unknown method.");
162 r = sd_bus_message_new_method_error(bus, m, &e, &reply);
164 log_error("Failed to allocate return: %s", strerror(-r));
170 r = sd_bus_send(bus, reply, NULL);
172 log_error("Failed to send reply: %s", strerror(-r));
176 /* log_info("Sent"); */
177 /* bus_message_dump(reply); */
178 /* sd_bus_message_rewind(reply, true); */
193 static void* client1(void*p) {
194 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
196 sd_bus_error error = SD_BUS_ERROR_INIT;
200 r = sd_bus_open_user(&bus);
202 log_error("Failed to connect to user bus: %s", strerror(-r));
206 r = sd_bus_message_new_method_call(
208 "org.freedesktop.systemd.test",
210 "org.freedesktop.systemd.test",
214 log_error("Failed to allocate method call: %s", strerror(-r));
218 r = sd_bus_message_append(m, "s", "HELLO");
220 log_error("Failed to append string: %s", strerror(-r));
224 r = sd_bus_send_with_reply_and_block(bus, m, 0, &error, &reply);
226 log_error("Failed to issue method call: %s", bus_error_message(&error, -r));
230 r = sd_bus_message_read(reply, "s", &hello);
232 log_error("Failed to get string: %s", strerror(-r));
236 assert(streq(hello, "hello"));
242 _cleanup_bus_message_unref_ sd_bus_message *q;
244 r = sd_bus_message_new_method_call(
246 "org.freedesktop.systemd.test",
248 "org.freedesktop.systemd.test",
252 log_error("Failed to allocate method call: %s", strerror(-r));
256 sd_bus_send(bus, q, NULL);
261 sd_bus_error_free(&error);
262 return INT_TO_PTR(r);
265 static int quit_callback(sd_bus *b, int ret, sd_bus_message *m, void *userdata) {
268 log_error("Quit callback: %s", strerror(ret));
274 static void* client2(void*p) {
275 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
277 sd_bus_error error = SD_BUS_ERROR_INIT;
282 r = sd_bus_open_user(&bus);
284 log_error("Failed to connect to user bus: %s", strerror(-r));
288 r = sd_bus_message_new_method_call(
290 "org.freedesktop.systemd.test",
292 "org.freedesktop.DBus.Peer",
296 log_error("Failed to allocate method call: %s", strerror(-r));
300 r = sd_bus_send_with_reply_and_block(bus, m, 0, &error, &reply);
302 log_error("Failed to issue method call: %s", bus_error_message(&error, -r));
306 r = sd_bus_message_read(reply, "s", &mid);
308 log_error("Failed to parse machine ID: %s", strerror(-r));
312 log_info("Machine ID is %s.", mid);
314 sd_bus_message_unref(m);
317 r = sd_bus_message_new_method_call(
319 "org.freedesktop.systemd.test",
321 "org.freedesktop.systemd.test",
325 log_error("Failed to allocate method call: %s", strerror(-r));
329 sd_bus_message_unref(reply);
332 r = sd_bus_send_with_reply_and_block(bus, m, 200 * USEC_PER_MSEC, &error, &reply);
334 log_info("Failed to issue method call: %s", bus_error_message(&error, -r));
336 log_info("Slow call succeed.");
338 sd_bus_message_unref(m);
341 r = sd_bus_message_new_method_call(
343 "org.freedesktop.systemd.test",
345 "org.freedesktop.systemd.test",
349 log_error("Failed to allocate method call: %s", strerror(-r));
353 r = sd_bus_send_with_reply(bus, m, quit_callback, &quit, 200 * USEC_PER_MSEC, NULL);
355 log_info("Failed to issue method call: %s", bus_error_message(&error, -r));
360 r = sd_bus_process(bus, NULL);
362 log_error("Failed to process requests: %s", strerror(-r));
366 r = sd_bus_wait(bus, (uint64_t) -1);
368 log_error("Failed to wait: %s", strerror(-r));
378 _cleanup_bus_message_unref_ sd_bus_message *q;
380 r = sd_bus_message_new_method_call(
382 "org.freedesktop.systemd.test",
384 "org.freedesktop.systemd.test",
388 log_error("Failed to allocate method call: %s", strerror(-r));
392 sd_bus_send(bus, q, NULL);
397 sd_bus_error_free(&error);
398 return INT_TO_PTR(r);
401 int main(int argc, char *argv[]) {
407 r = server_init(&bus);
411 log_info("Initialized...");
413 r = pthread_create(&c1, NULL, client1, bus);
417 r = pthread_create(&c2, NULL, client2, bus);
423 q = pthread_join(c1, &p);
426 q = pthread_join(c2, &p);