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;
159 assert_return(call, -EINVAL);
160 assert_return(call->sealed, -EPERM);
161 assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
162 assert_return(call->bus && BUS_IS_OPEN(call->bus->state), -ENOTCONN);
163 assert_return(!bus_pid_changed(call->bus), -ECHILD);
165 if (call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED)
168 va_start(ap, format);
169 bus_error_setfv(&error, name, format, ap);
172 return sd_bus_reply_method_error(call, &error);
175 _public_ int sd_bus_reply_method_errno(
176 sd_bus_message *call,
178 const sd_bus_error *p) {
180 _cleanup_bus_error_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
182 assert_return(call, -EINVAL);
183 assert_return(call->sealed, -EPERM);
184 assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
185 assert_return(call->bus && BUS_IS_OPEN(call->bus->state), -ENOTCONN);
186 assert_return(!bus_pid_changed(call->bus), -ECHILD);
188 if (call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED)
191 if (sd_bus_error_is_set(p))
192 return sd_bus_reply_method_error(call, p);
194 sd_bus_error_set_errno(&berror, error);
196 return sd_bus_reply_method_error(call, &berror);
199 _public_ int sd_bus_reply_method_errnof(
200 sd_bus_message *call,
205 _cleanup_bus_error_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
208 assert_return(call, -EINVAL);
209 assert_return(call->sealed, -EPERM);
210 assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
211 assert_return(call->bus && BUS_IS_OPEN(call->bus->state), -ENOTCONN);
212 assert_return(!bus_pid_changed(call->bus), -ECHILD);
214 if (call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED)
217 va_start(ap, format);
218 bus_error_set_errnofv(&berror, error, format, ap);
221 return sd_bus_reply_method_error(call, &berror);
224 _public_ int sd_bus_get_property(
226 const char *destination,
228 const char *interface,
231 sd_bus_message **reply,
234 sd_bus_message *rep = NULL;
237 assert_return(bus, -EINVAL);
238 assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL);
239 assert_return(member_name_is_valid(member), -EINVAL);
240 assert_return(reply, -EINVAL);
241 assert_return(signature_is_single(type, false), -EINVAL);
242 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
243 assert_return(!bus_pid_changed(bus), -ECHILD);
245 r = sd_bus_call_method(bus, destination, path, "org.freedesktop.DBus.Properties", "Get", error, &rep, "ss", strempty(interface), member);
249 r = sd_bus_message_enter_container(rep, 'v', type);
251 sd_bus_message_unref(rep);
259 _public_ int sd_bus_get_property_trivial(
261 const char *destination,
263 const char *interface,
266 char type, void *ptr) {
268 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
271 assert_return(bus, -EINVAL);
272 assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL);
273 assert_return(member_name_is_valid(member), -EINVAL);
274 assert_return(bus_type_is_trivial(type), -EINVAL);
275 assert_return(ptr, -EINVAL);
276 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
277 assert_return(!bus_pid_changed(bus), -ECHILD);
279 r = sd_bus_call_method(bus, destination, path, "org.freedesktop.DBus.Properties", "Get", error, &reply, "ss", strempty(interface), member);
283 r = sd_bus_message_enter_container(reply, 'v', CHAR_TO_STR(type));
287 r = sd_bus_message_read_basic(reply, type, ptr);
294 _public_ int sd_bus_get_property_string(
296 const char *destination,
298 const char *interface,
303 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
308 assert_return(bus, -EINVAL);
309 assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL);
310 assert_return(member_name_is_valid(member), -EINVAL);
311 assert_return(ret, -EINVAL);
312 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
313 assert_return(!bus_pid_changed(bus), -ECHILD);
315 r = sd_bus_call_method(bus, destination, path, "org.freedesktop.DBus.Properties", "Get", error, &reply, "ss", strempty(interface), member);
319 r = sd_bus_message_enter_container(reply, 'v', "s");
323 r = sd_bus_message_read_basic(reply, 's', &s);
335 _public_ int sd_bus_get_property_strv(
337 const char *destination,
339 const char *interface,
344 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
347 assert_return(bus, -EINVAL);
348 assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL);
349 assert_return(member_name_is_valid(member), -EINVAL);
350 assert_return(ret, -EINVAL);
351 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
352 assert_return(!bus_pid_changed(bus), -ECHILD);
354 r = sd_bus_call_method(bus, destination, path, "org.freedesktop.DBus.Properties", "Get", error, &reply, "ss", strempty(interface), member);
358 r = sd_bus_message_enter_container(reply, 'v', NULL);
362 r = sd_bus_message_read_strv(reply, ret);
369 _public_ int sd_bus_set_property(
371 const char *destination,
373 const char *interface,
376 const char *type, ...) {
378 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
382 assert_return(bus, -EINVAL);
383 assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL);
384 assert_return(member_name_is_valid(member), -EINVAL);
385 assert_return(signature_is_single(type, false), -EINVAL);
386 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
387 assert_return(!bus_pid_changed(bus), -ECHILD);
389 r = sd_bus_message_new_method_call(bus, destination, path, "org.freedesktop.DBus.Properties", "Set", &m);
393 r = sd_bus_message_append(m, "ss", strempty(interface), member);
397 r = sd_bus_message_open_container(m, 'v', type);
402 r = bus_message_append_ap(m, type, ap);
407 r = sd_bus_message_close_container(m);
411 return sd_bus_call(bus, m, 0, error, NULL);