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) {
42 r = sd_bus_open_user(&bus);
44 log_error("Failed to connect to user bus: %s", strerror(-r));
48 r = sd_bus_get_peer(bus, &id);
50 log_error("Failed to get peer ID: %s", strerror(-r));
54 r = sd_bus_get_unique_name(bus, &unique);
56 log_error("Failed to get unique name: %s", strerror(-r));
60 log_info("Peer ID is " SD_ID128_FORMAT_STR ".", SD_ID128_FORMAT_VAL(id));
61 log_info("Unique ID: %s", unique);
62 log_info("Can send file handles: %i", sd_bus_can_send(bus, 'h'));
64 r = sd_bus_request_name(bus, "org.freedesktop.systemd.test", 0);
66 log_error("Failed to acquire name: %s", strerror(-r));
80 static int server(sd_bus *bus) {
82 bool client1_gone = false, client2_gone = false;
84 while (!client1_gone || !client2_gone) {
85 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
88 r = sd_bus_process(bus, &m);
90 log_error("Failed to process requests: %s", strerror(-r));
95 r = sd_bus_wait(bus, (uint64_t) -1);
97 log_error("Failed to wait: %s", strerror(-r));
107 sd_bus_message_get_pid(m, &pid);
108 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)));
109 /* bus_message_dump(m); */
110 /* sd_bus_message_rewind(m, true); */
112 if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "LowerCase")) {
114 _cleanup_free_ char *lowercase = NULL;
116 r = sd_bus_message_read(m, "s", &hello);
118 log_error("Failed to get parameter: %s", strerror(-r));
122 r = sd_bus_message_new_method_return(bus, m, &reply);
124 log_error("Failed to allocate return: %s", strerror(-r));
128 lowercase = strdup(hello);
134 ascii_strlower(lowercase);
136 r = sd_bus_message_append(reply, "s", lowercase);
138 log_error("Failed to append message: %s", strerror(-r));
141 } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "ExitClient1")) {
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", "ExitClient2")) {
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, "org.freedesktop.systemd.test", "Slow")) {
161 r = sd_bus_message_new_method_return(bus, m, &reply);
163 log_error("Failed to allocate return: %s", strerror(-r));
168 } else if (sd_bus_message_is_method_call(m, NULL, NULL)) {
169 const sd_bus_error e = SD_BUS_ERROR_INIT_CONST("org.freedesktop.DBus.Error.UnknownMethod", "Unknown method.");
171 r = sd_bus_message_new_method_error(bus, m, &e, &reply);
173 log_error("Failed to allocate return: %s", strerror(-r));
179 r = sd_bus_send(bus, reply, NULL);
181 log_error("Failed to send reply: %s", strerror(-r));
185 /* log_info("Sent"); */
186 /* bus_message_dump(reply); */
187 /* sd_bus_message_rewind(reply, true); */
202 static void* client1(void*p) {
203 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
205 sd_bus_error error = SD_BUS_ERROR_INIT;
209 r = sd_bus_open_user(&bus);
211 log_error("Failed to connect to user bus: %s", strerror(-r));
215 r = sd_bus_message_new_method_call(
217 "org.freedesktop.systemd.test",
219 "org.freedesktop.systemd.test",
223 log_error("Failed to allocate method call: %s", strerror(-r));
227 r = sd_bus_message_append(m, "s", "HELLO");
229 log_error("Failed to append string: %s", strerror(-r));
233 r = sd_bus_send_with_reply_and_block(bus, m, 0, &error, &reply);
235 log_error("Failed to issue method call: %s", bus_error_message(&error, -r));
239 r = sd_bus_message_read(reply, "s", &hello);
241 log_error("Failed to get string: %s", strerror(-r));
245 assert(streq(hello, "hello"));
251 _cleanup_bus_message_unref_ sd_bus_message *q;
253 r = sd_bus_message_new_method_call(
255 "org.freedesktop.systemd.test",
257 "org.freedesktop.systemd.test",
261 log_error("Failed to allocate method call: %s", strerror(-r));
265 sd_bus_send(bus, q, NULL);
270 sd_bus_error_free(&error);
271 return INT_TO_PTR(r);
274 static int quit_callback(sd_bus *b, int ret, sd_bus_message *m, void *userdata) {
277 log_error("Quit callback: %s", strerror(ret));
283 static void* client2(void*p) {
284 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
286 sd_bus_error error = SD_BUS_ERROR_INIT;
291 r = sd_bus_open_user(&bus);
293 log_error("Failed to connect to user bus: %s", strerror(-r));
297 r = sd_bus_message_new_method_call(
299 "org.freedesktop.systemd.test",
301 "org.freedesktop.DBus.Peer",
305 log_error("Failed to allocate method call: %s", strerror(-r));
309 r = sd_bus_send_with_reply_and_block(bus, m, 0, &error, &reply);
311 log_error("Failed to issue method call: %s", bus_error_message(&error, -r));
315 r = sd_bus_message_read(reply, "s", &mid);
317 log_error("Failed to parse machine ID: %s", strerror(-r));
321 log_info("Machine ID is %s.", mid);
323 sd_bus_message_unref(m);
326 r = sd_bus_message_new_method_call(
328 "org.freedesktop.systemd.test",
330 "org.freedesktop.systemd.test",
334 log_error("Failed to allocate method call: %s", strerror(-r));
338 sd_bus_message_unref(reply);
341 r = sd_bus_send_with_reply_and_block(bus, m, 200 * USEC_PER_MSEC, &error, &reply);
343 log_info("Failed to issue method call: %s", bus_error_message(&error, -r));
345 log_info("Slow call succeed.");
347 sd_bus_message_unref(m);
350 r = sd_bus_message_new_method_call(
352 "org.freedesktop.systemd.test",
354 "org.freedesktop.systemd.test",
358 log_error("Failed to allocate method call: %s", strerror(-r));
362 r = sd_bus_send_with_reply(bus, m, quit_callback, &quit, 200 * USEC_PER_MSEC, NULL);
364 log_info("Failed to issue method call: %s", bus_error_message(&error, -r));
369 r = sd_bus_process(bus, NULL);
371 log_error("Failed to process requests: %s", strerror(-r));
375 r = sd_bus_wait(bus, (uint64_t) -1);
377 log_error("Failed to wait: %s", strerror(-r));
387 _cleanup_bus_message_unref_ sd_bus_message *q;
389 r = sd_bus_message_new_method_call(
391 "org.freedesktop.systemd.test",
393 "org.freedesktop.systemd.test",
397 log_error("Failed to allocate method call: %s", strerror(-r));
401 sd_bus_send(bus, q, NULL);
406 sd_bus_error_free(&error);
407 return INT_TO_PTR(r);
410 int main(int argc, char *argv[]) {
416 r = server_init(&bus);
420 log_info("Initialized...");
422 r = pthread_create(&c1, NULL, client1, bus);
426 r = pthread_create(&c2, NULL, client2, bus);
432 q = pthread_join(c1, &p);
435 q = pthread_join(c2, &p);