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"
26 int sd_bus_emit_signal(
29 const char *interface,
31 const char *types, ...) {
33 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
36 assert_return(bus, -EINVAL);
37 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
38 assert_return(!bus_pid_changed(bus), -ECHILD);
40 r = sd_bus_message_new_signal(bus, path, interface, member, &m);
44 if (!isempty(types)) {
48 r = bus_message_append_ap(m, types, ap);
54 return sd_bus_send(bus, m, NULL);
57 int sd_bus_call_method(
59 const char *destination,
61 const char *interface,
64 sd_bus_message **reply,
65 const char *types, ...) {
67 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
70 assert_return(bus, -EINVAL);
71 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
72 assert_return(!bus_pid_changed(bus), -ECHILD);
74 r = sd_bus_message_new_method_call(bus, destination, path, interface, member, &m);
78 if (!isempty(types)) {
82 r = bus_message_append_ap(m, types, ap);
88 return sd_bus_send_with_reply_and_block(bus, m, 0, error, reply);
91 int sd_bus_reply_method_return(
94 const char *types, ...) {
96 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
99 assert_return(bus, -EINVAL);
100 assert_return(call, -EINVAL);
101 assert_return(call->sealed, -EPERM);
102 assert_return(call->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL, -EINVAL);
103 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
104 assert_return(!bus_pid_changed(bus), -ECHILD);
106 if (call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED)
109 r = sd_bus_message_new_method_return(bus, call, &m);
113 if (!isempty(types)) {
117 r = bus_message_append_ap(m, types, ap);
123 return sd_bus_send(bus, m, NULL);
126 int sd_bus_reply_method_error(
128 sd_bus_message *call,
129 const sd_bus_error *e) {
131 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
134 assert_return(bus, -EINVAL);
135 assert_return(call, -EINVAL);
136 assert_return(call->sealed, -EPERM);
137 assert_return(call->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL, -EINVAL);
138 assert_return(sd_bus_error_is_set(e), -EINVAL);
139 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
140 assert_return(!bus_pid_changed(bus), -ECHILD);
142 if (call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED)
145 r = sd_bus_message_new_method_error(bus, call, e, &m);
149 return sd_bus_send(bus, m, NULL);
152 int sd_bus_reply_method_errorf(
154 sd_bus_message *call,
159 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
163 assert_return(bus, -EINVAL);
164 assert_return(call, -EINVAL);
165 assert_return(call->sealed, -EPERM);
166 assert_return(call->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL, -EINVAL);
167 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
168 assert_return(!bus_pid_changed(bus), -ECHILD);
170 if (call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED)
173 error.name = strdup(name);
177 error.need_free = true;
180 va_start(ap, format);
181 r = vasprintf((char**) &error.message, format, ap);
188 return sd_bus_reply_method_error(bus, call, &error);
191 int sd_bus_get_property(
193 const char *destination,
195 const char *interface,
198 sd_bus_message **reply,
201 sd_bus_message *rep = NULL;
204 assert_return(bus, -EINVAL);
205 assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL);
206 assert_return(member_name_is_valid(member), -EINVAL);
207 assert_return(reply, -EINVAL);
208 assert_return(signature_is_single(type, false), -EINVAL);
209 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
210 assert_return(!bus_pid_changed(bus), -ECHILD);
212 r = sd_bus_call_method(bus, destination, path, "org.freedesktop.DBus.Properties", "Get", error, &rep, "ss", strempty(interface), member);
216 r = sd_bus_message_enter_container(rep, 'v', type);
218 sd_bus_message_unref(rep);
226 int sd_bus_set_property(
228 const char *destination,
230 const char *interface,
233 const char *type, ...) {
235 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
239 assert_return(bus, -EINVAL);
240 assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL);
241 assert_return(member_name_is_valid(member), -EINVAL);
242 assert_return(signature_is_single(type, false), -EINVAL);
243 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
244 assert_return(!bus_pid_changed(bus), -ECHILD);
246 r = sd_bus_message_new_method_call(bus, destination, path, "org.freedesktop.DBus.Properties", "Set", &m);
250 r = sd_bus_message_append(m, "ss", strempty(interface), member);
254 r = sd_bus_message_open_container(m, 'v', type);
259 r = bus_message_append_ap(m, type, ap);
264 r = sd_bus_message_close_container(m);
268 return sd_bus_send_with_reply_and_block(bus, m, 0, error, NULL);