chiark / gitweb /
bus-message: fix typo
[elogind.git] / src / libsystemd-bus / test-bus-chat.c
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
32 static 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
53 fail:
54         if (bus)
55                 sd_bus_unref(bus);
56
57         return r;
58 }
59
60 static 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
138 fail:
139         if (bus)
140                 sd_bus_unref(bus);
141
142         return INT_TO_PTR(r);
143 }
144
145 static 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
192 finish:
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
217 int 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 }