]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd-bus/test-bus-chat.c
hwdb: update
[thirdparty/systemd.git] / src / libsystemd-bus / test-bus-chat.c
CommitLineData
89ffcd2a
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2013 Lennart Poettering
7
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.
12
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.
17
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/>.
20***/
21
22#include <assert.h>
23#include <stdlib.h>
24#include <pthread.h>
25
26#include "log.h"
27#include "util.h"
28
29#include "sd-bus.h"
30#include "bus-message.h"
31
32static int server_init(sd_bus **_bus) {
33 sd_bus *bus = NULL;
34 int r;
35
36 assert(_bus);
37
38 r = sd_bus_open_user(&bus);
39 if (r < 0) {
40 log_error("Failed to connect to user bus: %s", strerror(-r));
41 goto fail;
42 }
43
44 r = sd_bus_request_name(bus, "org.freedesktop.systemd.test", 0);
45 if (r < 0) {
46 log_error("Failed to acquire name: %s", strerror(-r));
47 goto fail;
48 }
49
50 *_bus = bus;
51 return 0;
52
53fail:
54 if (bus)
55 sd_bus_unref(bus);
56
57 return r;
58}
59
60static void* server(void *p) {
61 sd_bus *bus = p;
62 int r;
63
64 for (;;) {
65 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
66
67 r = sd_bus_process(bus, &m);
68 if (r < 0) {
69 log_error("Failed to process requests: %s", strerror(-r));
70 goto fail;
71 }
72 if (r == 0) {
73 r = sd_bus_wait(bus, (uint64_t) -1);
74 if (r < 0) {
75 log_error("Failed to wait: %s", strerror(-r));
76 goto fail;
77 }
78
79 continue;
80 }
81
82 log_info("Got message! %s", strna(sd_bus_message_get_member(m)));
83 /* bus_message_dump(m); */
84 /* sd_bus_message_rewind(m, true); */
85
86 if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "LowerCase")) {
87 const char *hello;
88 _cleanup_free_ char *lowercase = NULL;
89
90 r = sd_bus_message_read(m, "s", &hello);
91 if (r < 0) {
92 log_error("Failed to get parameter: %s", strerror(-r));
93 goto fail;
94 }
95
96 r = sd_bus_message_new_method_return(bus, m, &reply);
97 if (r < 0) {
98 log_error("Failed to allocate return: %s", strerror(-r));
99 goto fail;
100 }
101
102 lowercase = strdup(hello);
103 if (!lowercase) {
104 r = log_oom();
105 goto fail;
106 }
107
108 ascii_strlower(lowercase);
109
110 r = sd_bus_message_append(reply, "s", lowercase);
111 if (r < 0) {
112 log_error("Failed to append message: %s", strerror(-r));
113 goto fail;
114 }
115 } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "Exit"))
116 break;
117 else if (sd_bus_message_is_method_call(m, NULL, NULL)) {
118 const sd_bus_error e = SD_BUS_ERROR_INIT_CONST("org.freedesktop.DBus.Error.UnknownMethod", "Unknown method.");
119
120 r = sd_bus_message_new_method_error(bus, m, &e, &reply);
121 if (r < 0) {
122 log_error("Failed to allocate return: %s", strerror(-r));
123 goto fail;
124 }
125 }
126
127 if (reply) {
128 r = sd_bus_send(bus, reply, NULL);
129 if (r < 0) {
130 log_error("Failed to send reply: %s", strerror(-r));
131 goto fail;
132 }
133 }
134 }
135
136 r = 0;
137
138fail:
139 if (bus)
140 sd_bus_unref(bus);
141
142 return INT_TO_PTR(r);
143}
144
145static int client(void) {
146 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
147 sd_bus *bus = NULL;
148 sd_bus_error error = SD_BUS_ERROR_INIT;
149 const char *hello;
150 int r;
151
152 r = sd_bus_open_user(&bus);
153 if (r < 0) {
154 log_error("Failed to connect to user bus: %s", strerror(-r));
155 goto finish;
156 }
157
158 r = sd_bus_message_new_method_call(
159 bus,
160 "org.freedesktop.systemd.test",
161 "/",
162 "org.freedesktop.systemd.test",
163 "LowerCase",
164 &m);
165 if (r < 0) {
166 log_error("Failed to allocate method call: %s", strerror(-r));
167 goto finish;
168 }
169
170 r = sd_bus_message_append(m, "s", "HELLO");
171 if (r < 0) {
172 log_error("Failed to append string: %s", strerror(-r));
173 goto finish;
174 }
175
176 r = sd_bus_send_with_reply_and_block(bus, m, (uint64_t) -1, &error, &reply);
177 if (r < 0) {
178 log_error("Failed to issue method call: %s", error.message);
179 goto finish;
180 }
181
182 r = sd_bus_message_read(reply, "s", &hello);
183 if (r < 0) {
184 log_error("Failed to get string: %s", strerror(-r));
185 goto finish;
186 }
187
188 assert(streq(hello, "hello"));
189
190 r = 0;
191
192finish:
193 if (bus) {
194 _cleanup_bus_message_unref_ sd_bus_message *q;
195
196 r = sd_bus_message_new_method_call(
197 bus,
198 "org.freedesktop.systemd.test",
199 "/",
200 "org.freedesktop.systemd.test",
201 "Exit",
202 &q);
203 if (r < 0) {
204 log_error("Failed to allocate method call: %s", strerror(-r));
205 goto finish;
206 }
207
208 sd_bus_send(bus, q, NULL);
209 sd_bus_flush(bus);
210 sd_bus_unref(bus);
211 }
212
213 sd_bus_error_free(&error);
214 return r;
215}
216
217int main(int argc, char *argv[]) {
218 pthread_t t;
219 sd_bus *bus;
220 void *p;
221 int q, r;
222
223 r = server_init(&bus);
224 if (r < 0)
225 return EXIT_FAILURE;
226
227 r = pthread_create(&t, NULL, server, bus);
228 if (r != 0) {
229 sd_bus_unref(bus);
230 return EXIT_FAILURE;
231 }
232
233 r = client();
234
235 q = pthread_join(t, &p);
236 if (q != 0)
237 return EXIT_FAILURE;
238 if (r < 0)
239 return EXIT_FAILURE;
240
241 return EXIT_SUCCESS;
242}