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_send_with_reply_and_block(bus
, m
, 0, error
, reply
);
93 _public_
int sd_bus_reply_method_return(
96 const char *types
, ...) {
98 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
101 assert_return(bus
, -EINVAL
);
102 assert_return(call
, -EINVAL
);
103 assert_return(call
->sealed
, -EPERM
);
104 assert_return(call
->header
->type
== SD_BUS_MESSAGE_METHOD_CALL
, -EINVAL
);
105 assert_return(BUS_IS_OPEN(bus
->state
), -ENOTCONN
);
106 assert_return(!bus_pid_changed(bus
), -ECHILD
);
108 if (call
->header
->flags
& SD_BUS_MESSAGE_NO_REPLY_EXPECTED
)
111 r
= sd_bus_message_new_method_return(bus
, call
, &m
);
115 if (!isempty(types
)) {
119 r
= bus_message_append_ap(m
, types
, ap
);
125 return sd_bus_send(bus
, m
, NULL
);
128 _public_
int sd_bus_reply_method_error(
130 sd_bus_message
*call
,
131 const sd_bus_error
*e
) {
133 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
136 assert_return(bus
, -EINVAL
);
137 assert_return(call
, -EINVAL
);
138 assert_return(call
->sealed
, -EPERM
);
139 assert_return(call
->header
->type
== SD_BUS_MESSAGE_METHOD_CALL
, -EINVAL
);
140 assert_return(sd_bus_error_is_set(e
), -EINVAL
);
141 assert_return(BUS_IS_OPEN(bus
->state
), -ENOTCONN
);
142 assert_return(!bus_pid_changed(bus
), -ECHILD
);
144 if (call
->header
->flags
& SD_BUS_MESSAGE_NO_REPLY_EXPECTED
)
147 r
= sd_bus_message_new_method_error(bus
, call
, e
, &m
);
151 return sd_bus_send(bus
, m
, NULL
);
154 _public_
int sd_bus_reply_method_errorf(
156 sd_bus_message
*call
,
161 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
165 assert_return(bus
, -EINVAL
);
166 assert_return(call
, -EINVAL
);
167 assert_return(call
->sealed
, -EPERM
);
168 assert_return(call
->header
->type
== SD_BUS_MESSAGE_METHOD_CALL
, -EINVAL
);
169 assert_return(BUS_IS_OPEN(bus
->state
), -ENOTCONN
);
170 assert_return(!bus_pid_changed(bus
), -ECHILD
);
172 if (call
->header
->flags
& SD_BUS_MESSAGE_NO_REPLY_EXPECTED
)
175 va_start(ap
, format
);
176 r
= bus_error_setfv(&error
, name
, format
, ap
);
182 return sd_bus_reply_method_error(bus
, call
, &error
);
185 _public_
int sd_bus_reply_method_errno(
187 sd_bus_message
*call
,
189 const sd_bus_error
*p
) {
191 _cleanup_bus_error_free_ sd_bus_error berror
= SD_BUS_ERROR_NULL
;
193 assert_return(bus
, -EINVAL
);
194 assert_return(call
, -EINVAL
);
195 assert_return(call
->sealed
, -EPERM
);
196 assert_return(call
->header
->type
== SD_BUS_MESSAGE_METHOD_CALL
, -EINVAL
);
197 assert_return(BUS_IS_OPEN(bus
->state
), -ENOTCONN
);
198 assert_return(!bus_pid_changed(bus
), -ECHILD
);
200 if (call
->header
->flags
& SD_BUS_MESSAGE_NO_REPLY_EXPECTED
)
203 if (sd_bus_error_is_set(p
))
204 return sd_bus_reply_method_error(bus
, call
, p
);
206 sd_bus_error_set_errno(&berror
, error
);
208 return sd_bus_reply_method_error(bus
, call
, &berror
);
211 _public_
int sd_bus_reply_method_errnof(
213 sd_bus_message
*call
,
218 _cleanup_bus_error_free_ sd_bus_error berror
= SD_BUS_ERROR_NULL
;
221 assert_return(bus
, -EINVAL
);
222 assert_return(call
, -EINVAL
);
223 assert_return(call
->sealed
, -EPERM
);
224 assert_return(call
->header
->type
== SD_BUS_MESSAGE_METHOD_CALL
, -EINVAL
);
225 assert_return(BUS_IS_OPEN(bus
->state
), -ENOTCONN
);
226 assert_return(!bus_pid_changed(bus
), -ECHILD
);
228 if (call
->header
->flags
& SD_BUS_MESSAGE_NO_REPLY_EXPECTED
)
231 va_start(ap
, format
);
232 bus_error_set_errnofv(&berror
, error
, format
, ap
);
235 return sd_bus_reply_method_error(bus
, call
, &berror
);
238 _public_
int sd_bus_get_property(
240 const char *destination
,
242 const char *interface
,
245 sd_bus_message
**reply
,
248 sd_bus_message
*rep
= NULL
;
251 assert_return(bus
, -EINVAL
);
252 assert_return(isempty(interface
) || interface_name_is_valid(interface
), -EINVAL
);
253 assert_return(member_name_is_valid(member
), -EINVAL
);
254 assert_return(reply
, -EINVAL
);
255 assert_return(signature_is_single(type
, false), -EINVAL
);
256 assert_return(BUS_IS_OPEN(bus
->state
), -ENOTCONN
);
257 assert_return(!bus_pid_changed(bus
), -ECHILD
);
259 r
= sd_bus_call_method(bus
, destination
, path
, "org.freedesktop.DBus.Properties", "Get", error
, &rep
, "ss", strempty(interface
), member
);
263 r
= sd_bus_message_enter_container(rep
, 'v', type
);
265 sd_bus_message_unref(rep
);
273 _public_
int sd_bus_get_property_trivial(
275 const char *destination
,
277 const char *interface
,
280 char type
, void *ptr
) {
282 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
285 assert_return(bus
, -EINVAL
);
286 assert_return(isempty(interface
) || interface_name_is_valid(interface
), -EINVAL
);
287 assert_return(member_name_is_valid(member
), -EINVAL
);
288 assert_return(bus_type_is_trivial(type
), -EINVAL
);
289 assert_return(ptr
, -EINVAL
);
290 assert_return(BUS_IS_OPEN(bus
->state
), -ENOTCONN
);
291 assert_return(!bus_pid_changed(bus
), -ECHILD
);
293 r
= sd_bus_call_method(bus
, destination
, path
, "org.freedesktop.DBus.Properties", "Get", error
, &reply
, "ss", strempty(interface
), member
);
297 r
= sd_bus_message_enter_container(reply
, 'v', CHAR_TO_STR(type
));
301 r
= sd_bus_message_read_basic(reply
, type
, ptr
);
308 _public_
int sd_bus_get_property_string(
310 const char *destination
,
312 const char *interface
,
317 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
322 assert_return(bus
, -EINVAL
);
323 assert_return(isempty(interface
) || interface_name_is_valid(interface
), -EINVAL
);
324 assert_return(member_name_is_valid(member
), -EINVAL
);
325 assert_return(ret
, -EINVAL
);
326 assert_return(BUS_IS_OPEN(bus
->state
), -ENOTCONN
);
327 assert_return(!bus_pid_changed(bus
), -ECHILD
);
329 r
= sd_bus_call_method(bus
, destination
, path
, "org.freedesktop.DBus.Properties", "Get", error
, &reply
, "ss", strempty(interface
), member
);
333 r
= sd_bus_message_enter_container(reply
, 'v', "s");
337 r
= sd_bus_message_read_basic(reply
, 's', &s
);
349 _public_
int sd_bus_get_property_strv(
351 const char *destination
,
353 const char *interface
,
358 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
361 assert_return(bus
, -EINVAL
);
362 assert_return(isempty(interface
) || interface_name_is_valid(interface
), -EINVAL
);
363 assert_return(member_name_is_valid(member
), -EINVAL
);
364 assert_return(ret
, -EINVAL
);
365 assert_return(BUS_IS_OPEN(bus
->state
), -ENOTCONN
);
366 assert_return(!bus_pid_changed(bus
), -ECHILD
);
368 r
= sd_bus_call_method(bus
, destination
, path
, "org.freedesktop.DBus.Properties", "Get", error
, &reply
, "ss", strempty(interface
), member
);
372 r
= sd_bus_message_enter_container(reply
, 'v', NULL
);
376 r
= sd_bus_message_read_strv(reply
, ret
);
383 _public_
int sd_bus_set_property(
385 const char *destination
,
387 const char *interface
,
390 const char *type
, ...) {
392 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
396 assert_return(bus
, -EINVAL
);
397 assert_return(isempty(interface
) || interface_name_is_valid(interface
), -EINVAL
);
398 assert_return(member_name_is_valid(member
), -EINVAL
);
399 assert_return(signature_is_single(type
, false), -EINVAL
);
400 assert_return(BUS_IS_OPEN(bus
->state
), -ENOTCONN
);
401 assert_return(!bus_pid_changed(bus
), -ECHILD
);
403 r
= sd_bus_message_new_method_call(bus
, destination
, path
, "org.freedesktop.DBus.Properties", "Set", &m
);
407 r
= sd_bus_message_append(m
, "ss", strempty(interface
), member
);
411 r
= sd_bus_message_open_container(m
, 'v', type
);
416 r
= bus_message_append_ap(m
, type
, ap
);
421 r
= sd_bus_message_close_container(m
);
425 return sd_bus_send_with_reply_and_block(bus
, m
, 0, error
, NULL
);