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/>.
22 #include "bus-internal.h"
23 #include "bus-message.h"
24 #include "bus-signature.h"
28 _public_ int sd_bus_emit_signal(
31 const char *interface,
33 const char *types, ...) {
35 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
38 assert_return(bus, -EINVAL);
39 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
40 assert_return(!bus_pid_changed(bus), -ECHILD);
42 r = sd_bus_message_new_signal(bus, path, interface, member, &m);
46 if (!isempty(types)) {
50 r = bus_message_append_ap(m, types, ap);
56 return sd_bus_send(bus, m, NULL);
59 _public_ int sd_bus_call_method(
61 const char *destination,
63 const char *interface,
66 sd_bus_message **reply,
67 const char *types, ...) {
69 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
72 assert_return(bus, -EINVAL);
73 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
74 assert_return(!bus_pid_changed(bus), -ECHILD);
76 r = sd_bus_message_new_method_call(bus, destination, path, interface, member, &m);
80 if (!isempty(types)) {
84 r = bus_message_append_ap(m, types, ap);
90 return sd_bus_call(bus, m, 0, error, reply);
93 _public_ int sd_bus_reply_method_return(
95 const char *types, ...) {
97 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
100 assert_return(call, -EINVAL);
101 assert_return(call->sealed, -EPERM);
102 assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
103 assert_return(call->bus && BUS_IS_OPEN(call->bus->state), -ENOTCONN);
104 assert_return(!bus_pid_changed(call->bus), -ECHILD);
106 if (call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED)
109 r = sd_bus_message_new_method_return(call, &m);
113 if (!isempty(types)) {
117 r = bus_message_append_ap(m, types, ap);
123 return sd_bus_send(call->bus, m, NULL);
126 _public_ int sd_bus_reply_method_error(
127 sd_bus_message *call,
128 const sd_bus_error *e) {
130 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
133 assert_return(call, -EINVAL);
134 assert_return(call->sealed, -EPERM);
135 assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
136 assert_return(sd_bus_error_is_set(e), -EINVAL);
137 assert_return(call->bus && BUS_IS_OPEN(call->bus->state), -ENOTCONN);
138 assert_return(!bus_pid_changed(call->bus), -ECHILD);
140 if (call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED)
143 r = sd_bus_message_new_method_error(call, e, &m);
147 return sd_bus_send(call->bus, m, NULL);
150 _public_ int sd_bus_reply_method_errorf(
151 sd_bus_message *call,
156 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
160 assert_return(call, -EINVAL);
161 assert_return(call->sealed, -EPERM);
162 assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
163 assert_return(call->bus && BUS_IS_OPEN(call->bus->state), -ENOTCONN);
164 assert_return(!bus_pid_changed(call->bus), -ECHILD);
166 if (call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED)
169 va_start(ap, format);
170 r = bus_error_setfv(&error, name, format, ap);
176 return sd_bus_reply_method_error(call, &error);
179 _public_ int sd_bus_reply_method_errno(
180 sd_bus_message *call,
182 const sd_bus_error *p) {
184 _cleanup_bus_error_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
186 assert_return(call, -EINVAL);
187 assert_return(call->sealed, -EPERM);
188 assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
189 assert_return(call->bus && BUS_IS_OPEN(call->bus->state), -ENOTCONN);
190 assert_return(!bus_pid_changed(call->bus), -ECHILD);
192 if (call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED)
195 if (sd_bus_error_is_set(p))
196 return sd_bus_reply_method_error(call, p);
198 sd_bus_error_set_errno(&berror, error);
200 return sd_bus_reply_method_error(call, &berror);
203 _public_ int sd_bus_reply_method_errnof(
204 sd_bus_message *call,
209 _cleanup_bus_error_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
212 assert_return(call, -EINVAL);
213 assert_return(call->sealed, -EPERM);
214 assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
215 assert_return(call->bus && BUS_IS_OPEN(call->bus->state), -ENOTCONN);
216 assert_return(!bus_pid_changed(call->bus), -ECHILD);
218 if (call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED)
221 va_start(ap, format);
222 bus_error_set_errnofv(&berror, error, format, ap);
225 return sd_bus_reply_method_error(call, &berror);
228 _public_ int sd_bus_get_property(
230 const char *destination,
232 const char *interface,
235 sd_bus_message **reply,
238 sd_bus_message *rep = NULL;
241 assert_return(bus, -EINVAL);
242 assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL);
243 assert_return(member_name_is_valid(member), -EINVAL);
244 assert_return(reply, -EINVAL);
245 assert_return(signature_is_single(type, false), -EINVAL);
246 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
247 assert_return(!bus_pid_changed(bus), -ECHILD);
249 r = sd_bus_call_method(bus, destination, path, "org.freedesktop.DBus.Properties", "Get", error, &rep, "ss", strempty(interface), member);
253 r = sd_bus_message_enter_container(rep, 'v', type);
255 sd_bus_message_unref(rep);
263 _public_ int sd_bus_get_property_trivial(
265 const char *destination,
267 const char *interface,
270 char type, void *ptr) {
272 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
275 assert_return(bus, -EINVAL);
276 assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL);
277 assert_return(member_name_is_valid(member), -EINVAL);
278 assert_return(bus_type_is_trivial(type), -EINVAL);
279 assert_return(ptr, -EINVAL);
280 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
281 assert_return(!bus_pid_changed(bus), -ECHILD);
283 r = sd_bus_call_method(bus, destination, path, "org.freedesktop.DBus.Properties", "Get", error, &reply, "ss", strempty(interface), member);
287 r = sd_bus_message_enter_container(reply, 'v', CHAR_TO_STR(type));
291 r = sd_bus_message_read_basic(reply, type, ptr);
298 _public_ int sd_bus_get_property_string(
300 const char *destination,
302 const char *interface,
307 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
312 assert_return(bus, -EINVAL);
313 assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL);
314 assert_return(member_name_is_valid(member), -EINVAL);
315 assert_return(ret, -EINVAL);
316 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
317 assert_return(!bus_pid_changed(bus), -ECHILD);
319 r = sd_bus_call_method(bus, destination, path, "org.freedesktop.DBus.Properties", "Get", error, &reply, "ss", strempty(interface), member);
323 r = sd_bus_message_enter_container(reply, 'v', "s");
327 r = sd_bus_message_read_basic(reply, 's', &s);
339 _public_ int sd_bus_get_property_strv(
341 const char *destination,
343 const char *interface,
348 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
351 assert_return(bus, -EINVAL);
352 assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL);
353 assert_return(member_name_is_valid(member), -EINVAL);
354 assert_return(ret, -EINVAL);
355 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
356 assert_return(!bus_pid_changed(bus), -ECHILD);
358 r = sd_bus_call_method(bus, destination, path, "org.freedesktop.DBus.Properties", "Get", error, &reply, "ss", strempty(interface), member);
362 r = sd_bus_message_enter_container(reply, 'v', NULL);
366 r = sd_bus_message_read_strv(reply, ret);
373 _public_ int sd_bus_set_property(
375 const char *destination,
377 const char *interface,
380 const char *type, ...) {
382 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
386 assert_return(bus, -EINVAL);
387 assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL);
388 assert_return(member_name_is_valid(member), -EINVAL);
389 assert_return(signature_is_single(type, false), -EINVAL);
390 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
391 assert_return(!bus_pid_changed(bus), -ECHILD);
393 r = sd_bus_message_new_method_call(bus, destination, path, "org.freedesktop.DBus.Properties", "Set", &m);
397 r = sd_bus_message_append(m, "ss", strempty(interface), member);
401 r = sd_bus_message_open_container(m, 'v', type);
406 r = bus_message_append_ap(m, type, ap);
411 r = sd_bus_message_close_container(m);
415 return sd_bus_call(bus, m, 0, error, NULL);