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 object_callback(sd_bus *bus, int error, sd_bus_message *m, void *userdata) {
42 if (sd_bus_message_is_method_call(m, "org.object.test", "Foobar")) {
43 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
45 log_info("Invoked Foobar() on %s", sd_bus_message_get_path(m));
47 r = sd_bus_message_new_method_return(bus, m, &reply);
49 log_error("Failed to allocate return: %s", strerror(-r));
53 r = sd_bus_send(bus, reply, NULL);
55 log_error("Failed to send reply: %s", strerror(-r));
65 static int server_init(sd_bus **_bus) {
73 r = sd_bus_open_user(&bus);
75 log_error("Failed to connect to user bus: %s", strerror(-r));
79 r = sd_bus_get_peer(bus, &id);
81 log_error("Failed to get peer ID: %s", strerror(-r));
85 r = sd_bus_get_unique_name(bus, &unique);
87 log_error("Failed to get unique name: %s", strerror(-r));
91 log_info("Peer ID is " SD_ID128_FORMAT_STR ".", SD_ID128_FORMAT_VAL(id));
92 log_info("Unique ID: %s", unique);
93 log_info("Can send file handles: %i", sd_bus_can_send(bus, 'h'));
95 r = sd_bus_request_name(bus, "org.freedesktop.systemd.test", 0);
97 log_error("Failed to acquire name: %s", strerror(-r));
101 r = sd_bus_add_fallback(bus, "/foo/bar", object_callback, NULL);
103 log_error("Failed to add object: %s", strerror(-r));
117 static int server(sd_bus *bus) {
119 bool client1_gone = false, client2_gone = false;
121 while (!client1_gone || !client2_gone) {
122 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
125 r = sd_bus_process(bus, &m);
127 log_error("Failed to process requests: %s", strerror(-r));
132 r = sd_bus_wait(bus, (uint64_t) -1);
134 log_error("Failed to wait: %s", strerror(-r));
144 sd_bus_message_get_pid(m, &pid);
145 log_info("Got message! member=%s pid=%lu label=%s", strna(sd_bus_message_get_member(m)), (unsigned long) pid, strna(sd_bus_message_get_label(m)));
146 /* bus_message_dump(m); */
147 /* sd_bus_message_rewind(m, true); */
149 if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "LowerCase")) {
151 _cleanup_free_ char *lowercase = NULL;
153 r = sd_bus_message_read(m, "s", &hello);
155 log_error("Failed to get parameter: %s", strerror(-r));
159 r = sd_bus_message_new_method_return(bus, m, &reply);
161 log_error("Failed to allocate return: %s", strerror(-r));
165 lowercase = strdup(hello);
171 ascii_strlower(lowercase);
173 r = sd_bus_message_append(reply, "s", lowercase);
175 log_error("Failed to append message: %s", strerror(-r));
178 } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "ExitClient1")) {
180 r = sd_bus_message_new_method_return(bus, m, &reply);
182 log_error("Failed to allocate return: %s", strerror(-r));
187 } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "ExitClient2")) {
189 r = sd_bus_message_new_method_return(bus, m, &reply);
191 log_error("Failed to allocate return: %s", strerror(-r));
196 } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "Slow")) {
198 r = sd_bus_message_new_method_return(bus, m, &reply);
200 log_error("Failed to allocate return: %s", strerror(-r));
205 } else if (sd_bus_message_is_method_call(m, NULL, NULL)) {
206 const sd_bus_error e = SD_BUS_ERROR_INIT_CONST("org.freedesktop.DBus.Error.UnknownMethod", "Unknown method.");
208 r = sd_bus_message_new_method_error(bus, m, &e, &reply);
210 log_error("Failed to allocate return: %s", strerror(-r));
216 r = sd_bus_send(bus, reply, NULL);
218 log_error("Failed to send reply: %s", strerror(-r));
222 /* log_info("Sent"); */
223 /* bus_message_dump(reply); */
224 /* sd_bus_message_rewind(reply, true); */
239 static void* client1(void*p) {
240 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
242 sd_bus_error error = SD_BUS_ERROR_INIT;
246 r = sd_bus_open_user(&bus);
248 log_error("Failed to connect to user bus: %s", strerror(-r));
252 r = sd_bus_message_new_method_call(
254 "org.freedesktop.systemd.test",
256 "org.freedesktop.systemd.test",
260 log_error("Failed to allocate method call: %s", strerror(-r));
264 r = sd_bus_message_append(m, "s", "HELLO");
266 log_error("Failed to append string: %s", strerror(-r));
270 r = sd_bus_send_with_reply_and_block(bus, m, 0, &error, &reply);
272 log_error("Failed to issue method call: %s", bus_error_message(&error, -r));
276 r = sd_bus_message_read(reply, "s", &hello);
278 log_error("Failed to get string: %s", strerror(-r));
282 assert(streq(hello, "hello"));
288 _cleanup_bus_message_unref_ sd_bus_message *q;
290 r = sd_bus_message_new_method_call(
292 "org.freedesktop.systemd.test",
294 "org.freedesktop.systemd.test",
298 log_error("Failed to allocate method call: %s", strerror(-r));
302 sd_bus_send(bus, q, NULL);
307 sd_bus_error_free(&error);
308 return INT_TO_PTR(r);
311 static int quit_callback(sd_bus *b, int ret, sd_bus_message *m, void *userdata) {
314 log_error("Quit callback: %s", strerror(ret));
320 static void* client2(void*p) {
321 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
323 sd_bus_error error = SD_BUS_ERROR_INIT;
328 r = sd_bus_open_user(&bus);
330 log_error("Failed to connect to user bus: %s", strerror(-r));
334 r = sd_bus_message_new_method_call(
336 "org.freedesktop.systemd.test",
337 "/foo/bar/waldo/piep",
342 log_error("Failed to allocate method call: %s", strerror(-r));
346 r = sd_bus_send(bus, m, NULL);
348 log_error("Failed to issue method call: %s", bus_error_message(&error, -r));
352 sd_bus_message_unref(m);
355 r = sd_bus_message_new_method_call(
357 "org.freedesktop.systemd.test",
359 "org.freedesktop.DBus.Peer",
363 log_error("Failed to allocate method call: %s", strerror(-r));
367 r = sd_bus_send_with_reply_and_block(bus, m, 0, &error, &reply);
369 log_error("Failed to issue method call: %s", bus_error_message(&error, -r));
373 r = sd_bus_message_read(reply, "s", &mid);
375 log_error("Failed to parse machine ID: %s", strerror(-r));
379 log_info("Machine ID is %s.", mid);
381 sd_bus_message_unref(m);
384 r = sd_bus_message_new_method_call(
386 "org.freedesktop.systemd.test",
388 "org.freedesktop.systemd.test",
392 log_error("Failed to allocate method call: %s", strerror(-r));
396 sd_bus_message_unref(reply);
399 r = sd_bus_send_with_reply_and_block(bus, m, 200 * USEC_PER_MSEC, &error, &reply);
401 log_info("Failed to issue method call: %s", bus_error_message(&error, -r));
403 log_info("Slow call succeed.");
405 sd_bus_message_unref(m);
408 r = sd_bus_message_new_method_call(
410 "org.freedesktop.systemd.test",
412 "org.freedesktop.systemd.test",
416 log_error("Failed to allocate method call: %s", strerror(-r));
420 r = sd_bus_send_with_reply(bus, m, quit_callback, &quit, 200 * USEC_PER_MSEC, NULL);
422 log_info("Failed to issue method call: %s", bus_error_message(&error, -r));
427 r = sd_bus_process(bus, NULL);
429 log_error("Failed to process requests: %s", strerror(-r));
433 r = sd_bus_wait(bus, (uint64_t) -1);
435 log_error("Failed to wait: %s", strerror(-r));
445 _cleanup_bus_message_unref_ sd_bus_message *q;
447 r = sd_bus_message_new_method_call(
449 "org.freedesktop.systemd.test",
451 "org.freedesktop.systemd.test",
455 log_error("Failed to allocate method call: %s", strerror(-r));
459 sd_bus_send(bus, q, NULL);
464 sd_bus_error_free(&error);
465 return INT_TO_PTR(r);
468 int main(int argc, char *argv[]) {
474 r = server_init(&bus);
478 log_info("Initialized...");
480 r = pthread_create(&c1, NULL, client1, bus);
484 r = pthread_create(&c2, NULL, client2, bus);
490 q = pthread_join(c1, &p);
493 q = pthread_join(c2, &p);