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;
87 r = sd_bus_process(bus, &m);
89 log_error("Failed to process requests: %s", strerror(-r));
94 r = sd_bus_wait(bus, (uint64_t) -1);
96 log_error("Failed to wait: %s", strerror(-r));
106 log_info("Got message! %s", strna(sd_bus_message_get_member(m)));
107 /* bus_message_dump(m); */
108 /* sd_bus_message_rewind(m, true); */
110 if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "LowerCase")) {
112 _cleanup_free_ char *lowercase = NULL;
114 r = sd_bus_message_read(m, "s", &hello);
116 log_error("Failed to get parameter: %s", strerror(-r));
120 r = sd_bus_message_new_method_return(bus, m, &reply);
122 log_error("Failed to allocate return: %s", strerror(-r));
126 lowercase = strdup(hello);
132 ascii_strlower(lowercase);
134 r = sd_bus_message_append(reply, "s", lowercase);
136 log_error("Failed to append message: %s", strerror(-r));
139 } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "ExitClient1")) {
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, "org.freedesktop.systemd.test", "ExitClient2")) {
150 r = sd_bus_message_new_method_return(bus, m, &reply);
152 log_error("Failed to allocate return: %s", strerror(-r));
157 } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "Slow")) {
159 r = sd_bus_message_new_method_return(bus, m, &reply);
161 log_error("Failed to allocate return: %s", strerror(-r));
166 } else if (sd_bus_message_is_method_call(m, NULL, NULL)) {
167 const sd_bus_error e = SD_BUS_ERROR_INIT_CONST("org.freedesktop.DBus.Error.UnknownMethod", "Unknown method.");
169 r = sd_bus_message_new_method_error(bus, m, &e, &reply);
171 log_error("Failed to allocate return: %s", strerror(-r));
177 r = sd_bus_send(bus, reply, NULL);
179 log_error("Failed to send reply: %s", strerror(-r));
183 /* log_info("Sent"); */
184 /* bus_message_dump(reply); */
185 /* sd_bus_message_rewind(reply, true); */
200 static void* client1(void*p) {
201 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
203 sd_bus_error error = SD_BUS_ERROR_INIT;
207 r = sd_bus_open_user(&bus);
209 log_error("Failed to connect to user bus: %s", strerror(-r));
213 r = sd_bus_message_new_method_call(
215 "org.freedesktop.systemd.test",
217 "org.freedesktop.systemd.test",
221 log_error("Failed to allocate method call: %s", strerror(-r));
225 r = sd_bus_message_append(m, "s", "HELLO");
227 log_error("Failed to append string: %s", strerror(-r));
231 r = sd_bus_send_with_reply_and_block(bus, m, 0, &error, &reply);
233 log_error("Failed to issue method call: %s", bus_error_message(&error, -r));
237 r = sd_bus_message_read(reply, "s", &hello);
239 log_error("Failed to get string: %s", strerror(-r));
243 assert(streq(hello, "hello"));
249 _cleanup_bus_message_unref_ sd_bus_message *q;
251 r = sd_bus_message_new_method_call(
253 "org.freedesktop.systemd.test",
255 "org.freedesktop.systemd.test",
259 log_error("Failed to allocate method call: %s", strerror(-r));
263 sd_bus_send(bus, q, NULL);
268 sd_bus_error_free(&error);
269 return INT_TO_PTR(r);
272 static int quit_callback(sd_bus *b, int ret, sd_bus_message *m, void *userdata) {
275 log_error("Quit callback: %s", strerror(ret));
281 static void* client2(void*p) {
282 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
284 sd_bus_error error = SD_BUS_ERROR_INIT;
289 r = sd_bus_open_user(&bus);
291 log_error("Failed to connect to user bus: %s", strerror(-r));
295 r = sd_bus_message_new_method_call(
297 "org.freedesktop.systemd.test",
299 "org.freedesktop.DBus.Peer",
303 log_error("Failed to allocate method call: %s", strerror(-r));
307 r = sd_bus_send_with_reply_and_block(bus, m, 0, &error, &reply);
309 log_error("Failed to issue method call: %s", bus_error_message(&error, -r));
313 r = sd_bus_message_read(reply, "s", &mid);
315 log_error("Failed to parse machine ID: %s", strerror(-r));
319 log_info("Machine ID is %s.", mid);
321 sd_bus_message_unref(m);
324 r = sd_bus_message_new_method_call(
326 "org.freedesktop.systemd.test",
328 "org.freedesktop.systemd.test",
332 log_error("Failed to allocate method call: %s", strerror(-r));
336 sd_bus_message_unref(reply);
339 r = sd_bus_send_with_reply_and_block(bus, m, 200 * USEC_PER_MSEC, &error, &reply);
341 log_info("Failed to issue method call: %s", bus_error_message(&error, -r));
343 log_info("Slow call succeed.");
345 sd_bus_message_unref(m);
348 r = sd_bus_message_new_method_call(
350 "org.freedesktop.systemd.test",
352 "org.freedesktop.systemd.test",
356 log_error("Failed to allocate method call: %s", strerror(-r));
360 r = sd_bus_send_with_reply(bus, m, quit_callback, &quit, 200 * USEC_PER_MSEC, NULL);
362 log_info("Failed to issue method call: %s", bus_error_message(&error, -r));
367 r = sd_bus_process(bus, NULL);
369 log_error("Failed to process requests: %s", strerror(-r));
373 r = sd_bus_wait(bus, (uint64_t) -1);
375 log_error("Failed to wait: %s", strerror(-r));
385 _cleanup_bus_message_unref_ sd_bus_message *q;
387 r = sd_bus_message_new_method_call(
389 "org.freedesktop.systemd.test",
391 "org.freedesktop.systemd.test",
395 log_error("Failed to allocate method call: %s", strerror(-r));
399 sd_bus_send(bus, q, NULL);
404 sd_bus_error_free(&error);
405 return INT_TO_PTR(r);
408 int main(int argc, char *argv[]) {
414 r = server_init(&bus);
418 log_info("Initialized...");
420 r = pthread_create(&c1, NULL, client1, bus);
424 r = pthread_create(&c2, NULL, client2, bus);
430 q = pthread_join(c1, &p);
433 q = pthread_join(c2, &p);