1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2013 Lennart Poettering
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
31 #include "alloc-util.h"
32 #include "bus-container.h"
33 #include "bus-control.h"
34 #include "bus-internal.h"
35 #include "bus-kernel.h"
36 #include "bus-label.h"
37 #include "bus-message.h"
38 #include "bus-objects.h"
39 #include "bus-protocol.h"
41 #include "bus-socket.h"
42 #include "bus-track.h"
45 #include "cgroup-util.h"
48 #include "hexdecoct.h"
49 #include "hostname-util.h"
52 #include "parse-util.h"
53 #include "string-util.h"
57 /// Additional includes needed by elogind
58 #include "process-util.h"
60 #define log_debug_bus_message(m) \
62 sd_bus_message *_mm = (m); \
63 log_debug("Got message type=%s sender=%s destination=%s object=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " error-name=%s error-message=%s", \
64 bus_message_type_to_string(_mm->header->type), \
65 strna(sd_bus_message_get_sender(_mm)), \
66 strna(sd_bus_message_get_destination(_mm)), \
67 strna(sd_bus_message_get_path(_mm)), \
68 strna(sd_bus_message_get_interface(_mm)), \
69 strna(sd_bus_message_get_member(_mm)), \
70 BUS_MESSAGE_COOKIE(_mm), \
72 strna(_mm->error.name), \
73 strna(_mm->error.message)); \
76 static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec);
77 static int attach_io_events(sd_bus *b);
78 static void detach_io_events(sd_bus *b);
80 static thread_local sd_bus *default_system_bus = NULL;
81 #if 0 /// UNNEEDED by elogind
82 static thread_local sd_bus *default_user_bus = NULL;
84 static thread_local sd_bus *default_starter_bus = NULL;
86 static void bus_close_fds(sd_bus *b) {
91 if (b->input_fd != b->output_fd)
92 safe_close(b->output_fd);
93 b->output_fd = b->input_fd = safe_close(b->input_fd);
96 static void bus_reset_queues(sd_bus *b) {
99 while (b->rqueue_size > 0)
100 sd_bus_message_unref(b->rqueue[--b->rqueue_size]);
102 b->rqueue = mfree(b->rqueue);
103 b->rqueue_allocated = 0;
105 while (b->wqueue_size > 0)
106 sd_bus_message_unref(b->wqueue[--b->wqueue_size]);
108 b->wqueue = mfree(b->wqueue);
109 b->wqueue_allocated = 0;
112 static void bus_free(sd_bus *b) {
116 assert(!b->track_queue);
119 b->state = BUS_CLOSED;
121 sd_bus_detach_event(b);
123 while ((s = b->slots)) {
124 /* At this point only floating slots can still be
125 * around, because the non-floating ones keep a
126 * reference to the bus, and we thus couldn't be
127 * destructing right now... We forcibly disconnect the
128 * slots here, so that they still can be referenced by
129 * apps, but are dead. */
132 bus_slot_disconnect(s);
133 sd_bus_slot_unref(s);
136 if (b->default_bus_ptr)
137 *b->default_bus_ptr = NULL;
143 free(b->unique_name);
144 free(b->auth_buffer);
147 free(b->cgroup_root);
148 free(b->description);
151 strv_free(b->exec_argv);
153 close_many(b->fds, b->n_fds);
158 ordered_hashmap_free_free(b->reply_callbacks);
159 prioq_free(b->reply_callbacks_prioq);
161 assert(b->match_callbacks.type == BUS_MATCH_ROOT);
162 bus_match_free(&b->match_callbacks);
164 hashmap_free_free(b->vtable_methods);
165 hashmap_free_free(b->vtable_properties);
167 assert(hashmap_isempty(b->nodes));
168 hashmap_free(b->nodes);
172 assert_se(pthread_mutex_destroy(&b->memfd_cache_mutex) == 0);
177 _public_ int sd_bus_new(sd_bus **ret) {
180 assert_return(ret, -EINVAL);
186 r->n_ref = REFCNT_INIT;
187 r->input_fd = r->output_fd = -1;
188 r->message_version = 1;
189 r->creds_mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME;
190 r->hello_flags |= KDBUS_HELLO_ACCEPT_FD;
191 r->attach_flags |= KDBUS_ATTACH_NAMES;
192 r->original_pid = getpid_cached();
194 assert_se(pthread_mutex_init(&r->memfd_cache_mutex, NULL) == 0);
196 /* We guarantee that wqueue always has space for at least one
198 if (!GREEDY_REALLOC(r->wqueue, r->wqueue_allocated, 1)) {
207 _public_ int sd_bus_set_address(sd_bus *bus, const char *address) {
210 assert_return(bus, -EINVAL);
211 assert_return(bus->state == BUS_UNSET, -EPERM);
212 assert_return(address, -EINVAL);
213 assert_return(!bus_pid_changed(bus), -ECHILD);
225 _public_ int sd_bus_set_fd(sd_bus *bus, int input_fd, int output_fd) {
226 assert_return(bus, -EINVAL);
227 assert_return(bus->state == BUS_UNSET, -EPERM);
228 assert_return(input_fd >= 0, -EBADF);
229 assert_return(output_fd >= 0, -EBADF);
230 assert_return(!bus_pid_changed(bus), -ECHILD);
232 bus->input_fd = input_fd;
233 bus->output_fd = output_fd;
237 _public_ int sd_bus_set_exec(sd_bus *bus, const char *path, char *const argv[]) {
240 assert_return(bus, -EINVAL);
241 assert_return(bus->state == BUS_UNSET, -EPERM);
242 assert_return(path, -EINVAL);
243 assert_return(!strv_isempty(argv), -EINVAL);
244 assert_return(!bus_pid_changed(bus), -ECHILD);
256 free(bus->exec_path);
257 strv_free(bus->exec_argv);
265 _public_ int sd_bus_set_bus_client(sd_bus *bus, int b) {
266 assert_return(bus, -EINVAL);
267 assert_return(bus->state == BUS_UNSET, -EPERM);
268 assert_return(!bus_pid_changed(bus), -ECHILD);
270 bus->bus_client = !!b;
274 _public_ int sd_bus_set_monitor(sd_bus *bus, int b) {
275 assert_return(bus, -EINVAL);
276 assert_return(bus->state == BUS_UNSET, -EPERM);
277 assert_return(!bus_pid_changed(bus), -ECHILD);
279 SET_FLAG(bus->hello_flags, KDBUS_HELLO_MONITOR, b);
283 _public_ int sd_bus_negotiate_fds(sd_bus *bus, int b) {
284 assert_return(bus, -EINVAL);
285 assert_return(bus->state == BUS_UNSET, -EPERM);
286 assert_return(!bus_pid_changed(bus), -ECHILD);
288 SET_FLAG(bus->hello_flags, KDBUS_HELLO_ACCEPT_FD, b);
292 _public_ int sd_bus_negotiate_timestamp(sd_bus *bus, int b) {
294 assert_return(bus, -EINVAL);
295 assert_return(!IN_SET(bus->state, BUS_CLOSING, BUS_CLOSED), -EPERM);
296 assert_return(!bus_pid_changed(bus), -ECHILD);
298 new_flags = bus->attach_flags;
299 SET_FLAG(new_flags, KDBUS_ATTACH_TIMESTAMP, b);
301 if (bus->attach_flags == new_flags)
304 bus->attach_flags = new_flags;
309 _public_ int sd_bus_negotiate_creds(sd_bus *bus, int b, uint64_t mask) {
312 assert_return(bus, -EINVAL);
313 assert_return(mask <= _SD_BUS_CREDS_ALL, -EINVAL);
314 assert_return(!IN_SET(bus->state, BUS_CLOSING, BUS_CLOSED), -EPERM);
315 assert_return(!bus_pid_changed(bus), -ECHILD);
317 SET_FLAG(bus->creds_mask, mask, b);
319 /* The well knowns we need unconditionally, so that matches can work */
320 bus->creds_mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME;
322 /* Make sure we don't lose the timestamp flag */
323 new_flags = (bus->attach_flags & KDBUS_ATTACH_TIMESTAMP) | attach_flags_to_kdbus(bus->creds_mask);
324 if (bus->attach_flags == new_flags)
327 bus->attach_flags = new_flags;
332 _public_ int sd_bus_set_server(sd_bus *bus, int b, sd_id128_t server_id) {
333 assert_return(bus, -EINVAL);
334 assert_return(b || sd_id128_equal(server_id, SD_ID128_NULL), -EINVAL);
335 assert_return(bus->state == BUS_UNSET, -EPERM);
336 assert_return(!bus_pid_changed(bus), -ECHILD);
338 bus->is_server = !!b;
339 bus->server_id = server_id;
343 _public_ int sd_bus_set_anonymous(sd_bus *bus, int b) {
344 assert_return(bus, -EINVAL);
345 assert_return(bus->state == BUS_UNSET, -EPERM);
346 assert_return(!bus_pid_changed(bus), -ECHILD);
348 bus->anonymous_auth = !!b;
352 _public_ int sd_bus_set_trusted(sd_bus *bus, int b) {
353 assert_return(bus, -EINVAL);
354 assert_return(bus->state == BUS_UNSET, -EPERM);
355 assert_return(!bus_pid_changed(bus), -ECHILD);
361 _public_ int sd_bus_set_description(sd_bus *bus, const char *description) {
362 assert_return(bus, -EINVAL);
363 assert_return(bus->state == BUS_UNSET, -EPERM);
364 assert_return(!bus_pid_changed(bus), -ECHILD);
366 return free_and_strdup(&bus->description, description);
369 _public_ int sd_bus_set_allow_interactive_authorization(sd_bus *bus, int b) {
370 assert_return(bus, -EINVAL);
371 assert_return(!bus_pid_changed(bus), -ECHILD);
373 bus->allow_interactive_authorization = !!b;
377 _public_ int sd_bus_get_allow_interactive_authorization(sd_bus *bus) {
378 assert_return(bus, -EINVAL);
379 assert_return(!bus_pid_changed(bus), -ECHILD);
381 return bus->allow_interactive_authorization;
384 static int hello_callback(sd_bus_message *reply, void *userdata, sd_bus_error *error) {
392 assert(IN_SET(bus->state, BUS_HELLO, BUS_CLOSING));
394 r = sd_bus_message_get_errno(reply);
398 r = sd_bus_message_read(reply, "s", &s);
402 if (!service_name_is_valid(s) || s[0] != ':')
405 bus->unique_name = strdup(s);
406 if (!bus->unique_name)
409 if (bus->state == BUS_HELLO)
410 bus->state = BUS_RUNNING;
415 static int bus_send_hello(sd_bus *bus) {
416 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
421 if (!bus->bus_client)
424 r = sd_bus_message_new_method_call(
427 "org.freedesktop.DBus",
428 "/org/freedesktop/DBus",
429 "org.freedesktop.DBus",
434 return sd_bus_call_async(bus, NULL, m, hello_callback, NULL, 0);
437 int bus_start_running(sd_bus *bus) {
440 if (bus->bus_client) {
441 bus->state = BUS_HELLO;
445 bus->state = BUS_RUNNING;
449 static int parse_address_key(const char **p, const char *key, char **value) {
450 size_t l, n = 0, allocated = 0;
460 if (strncmp(*p, key, l) != 0)
473 while (!IN_SET(*a, ';', ',', 0)) {
491 c = (char) ((x << 4) | y);
498 if (!GREEDY_REALLOC(r, allocated, n + 2))
522 static void skip_address_key(const char **p) {
526 *p += strcspn(*p, ",");
532 static int parse_unix_address(sd_bus *b, const char **p, char **guid) {
533 _cleanup_free_ char *path = NULL, *abstract = NULL;
542 while (!IN_SET(**p, 0, ';')) {
543 r = parse_address_key(p, "guid", guid);
549 r = parse_address_key(p, "path", &path);
555 r = parse_address_key(p, "abstract", &abstract);
564 if (!path && !abstract)
567 if (path && abstract)
572 if (l > sizeof(b->sockaddr.un.sun_path))
575 b->sockaddr.un.sun_family = AF_UNIX;
576 strncpy(b->sockaddr.un.sun_path, path, sizeof(b->sockaddr.un.sun_path));
577 b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + l;
578 } else if (abstract) {
579 l = strlen(abstract);
580 if (l > sizeof(b->sockaddr.un.sun_path) - 1)
583 b->sockaddr.un.sun_family = AF_UNIX;
584 b->sockaddr.un.sun_path[0] = 0;
585 strncpy(b->sockaddr.un.sun_path+1, abstract, sizeof(b->sockaddr.un.sun_path)-1);
586 b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + 1 + l;
594 static int parse_tcp_address(sd_bus *b, const char **p, char **guid) {
595 _cleanup_free_ char *host = NULL, *port = NULL, *family = NULL;
597 struct addrinfo *result, hints = {
598 .ai_socktype = SOCK_STREAM,
599 .ai_flags = AI_ADDRCONFIG,
607 while (!IN_SET(**p, 0, ';')) {
608 r = parse_address_key(p, "guid", guid);
614 r = parse_address_key(p, "host", &host);
620 r = parse_address_key(p, "port", &port);
626 r = parse_address_key(p, "family", &family);
639 if (streq(family, "ipv4"))
640 hints.ai_family = AF_INET;
641 else if (streq(family, "ipv6"))
642 hints.ai_family = AF_INET6;
647 r = getaddrinfo(host, port, &hints, &result);
651 return -EADDRNOTAVAIL;
653 memcpy(&b->sockaddr, result->ai_addr, result->ai_addrlen);
654 b->sockaddr_size = result->ai_addrlen;
656 freeaddrinfo(result);
663 static int parse_exec_address(sd_bus *b, const char **p, char **guid) {
665 unsigned n_argv = 0, j;
667 size_t allocated = 0;
675 while (!IN_SET(**p, 0, ';')) {
676 r = parse_address_key(p, "guid", guid);
682 r = parse_address_key(p, "path", &path);
688 if (startswith(*p, "argv")) {
692 ul = strtoul(*p + 4, (char**) p, 10);
693 if (errno > 0 || **p != '=' || ul > 256) {
701 if (!GREEDY_REALLOC0(argv, allocated, ul + 2)) {
709 r = parse_address_key(p, NULL, argv + ul);
724 /* Make sure there are no holes in the array, with the
725 * exception of argv[0] */
726 for (j = 1; j < n_argv; j++)
732 if (argv && argv[0] == NULL) {
733 argv[0] = strdup(path);
748 for (j = 0; j < n_argv; j++)
756 static int parse_container_unix_address(sd_bus *b, const char **p, char **guid) {
757 _cleanup_free_ char *machine = NULL, *pid = NULL;
765 while (!IN_SET(**p, 0, ';')) {
766 r = parse_address_key(p, "guid", guid);
772 r = parse_address_key(p, "machine", &machine);
778 r = parse_address_key(p, "pid", &pid);
787 if (!machine == !pid)
791 if (!machine_name_is_valid(machine))
794 free_and_replace(b->machine, machine);
796 b->machine = mfree(b->machine);
800 r = parse_pid(pid, &b->nspid);
806 b->sockaddr.un.sun_family = AF_UNIX;
807 strncpy(b->sockaddr.un.sun_path, "/var/run/dbus/system_bus_socket", sizeof(b->sockaddr.un.sun_path));
808 b->sockaddr_size = SOCKADDR_UN_LEN(b->sockaddr.un);
814 static void bus_reset_parsed_address(sd_bus *b) {
818 b->sockaddr_size = 0;
819 b->exec_argv = strv_free(b->exec_argv);
820 b->exec_path = mfree(b->exec_path);
821 b->server_id = SD_ID128_NULL;
822 b->machine = mfree(b->machine);
826 static int bus_parse_next_address(sd_bus *b) {
827 _cleanup_free_ char *guid = NULL;
835 if (b->address[b->address_index] == 0)
838 bus_reset_parsed_address(b);
840 a = b->address + b->address_index;
849 if (startswith(a, "unix:")) {
852 r = parse_unix_address(b, &a, &guid);
857 } else if (startswith(a, "tcp:")) {
860 r = parse_tcp_address(b, &a, &guid);
866 } else if (startswith(a, "unixexec:")) {
869 r = parse_exec_address(b, &a, &guid);
875 } else if (startswith(a, "x-machine-unix:")) {
878 r = parse_container_unix_address(b, &a, &guid);
891 r = sd_id128_from_string(guid, &b->server_id);
896 b->address_index = a - b->address;
900 static int bus_start_address(sd_bus *b) {
908 /* If you provide multiple different bus-addresses, we
909 * try all of them in order and use the first one that
913 r = bus_socket_exec(b);
915 else if ((b->nspid > 0 || b->machine) && b->sockaddr.sa.sa_family != AF_UNSPEC)
916 r = bus_container_connect_socket(b);
918 else if (b->sockaddr.sa.sa_family != AF_UNSPEC)
919 r = bus_socket_connect(b);
925 r = attach_io_events(b);
930 b->last_connect_error = -r;
933 r = bus_parse_next_address(b);
937 return b->last_connect_error > 0 ? -b->last_connect_error : -ECONNREFUSED;
941 int bus_next_address(sd_bus *b) {
944 bus_reset_parsed_address(b);
945 return bus_start_address(b);
948 static int bus_start_fd(sd_bus *b) {
953 assert(b->input_fd >= 0);
954 assert(b->output_fd >= 0);
956 r = fd_nonblock(b->input_fd, true);
960 r = fd_cloexec(b->input_fd, true);
964 if (b->input_fd != b->output_fd) {
965 r = fd_nonblock(b->output_fd, true);
969 r = fd_cloexec(b->output_fd, true);
974 if (fstat(b->input_fd, &st) < 0)
977 return bus_socket_take_fd(b);
980 _public_ int sd_bus_start(sd_bus *bus) {
983 assert_return(bus, -EINVAL);
984 assert_return(bus->state == BUS_UNSET, -EPERM);
985 assert_return(!bus_pid_changed(bus), -ECHILD);
987 bus->state = BUS_OPENING;
989 if (bus->is_server && bus->bus_client)
992 if (bus->input_fd >= 0)
993 r = bus_start_fd(bus);
994 else if (bus->address || bus->sockaddr.sa.sa_family != AF_UNSPEC || bus->exec_path || bus->machine)
995 r = bus_start_address(bus);
1004 return bus_send_hello(bus);
1007 _public_ int sd_bus_open(sd_bus **ret) {
1012 assert_return(ret, -EINVAL);
1014 /* Let's connect to the starter bus if it is set, and
1015 * otherwise to the bus that is appropropriate for the scope
1016 * we are running in */
1018 e = secure_getenv("DBUS_STARTER_BUS_TYPE");
1020 if (streq(e, "system"))
1021 return sd_bus_open_system(ret);
1022 #if 0 /// elogind does not support systemd user instances
1023 else if (STR_IN_SET(e, "session", "user"))
1024 return sd_bus_open_user(ret);
1028 e = secure_getenv("DBUS_STARTER_ADDRESS");
1030 #if 0 /// elogind does not support systemd user instances
1031 if (cg_pid_get_owner_uid(0, NULL) >= 0)
1032 return sd_bus_open_user(ret);
1035 return sd_bus_open_system(ret);
1042 r = sd_bus_set_address(b, e);
1046 b->bus_client = true;
1048 /* We don't know whether the bus is trusted or not, so better
1049 * be safe, and authenticate everything */
1051 b->is_local = false;
1052 b->attach_flags |= KDBUS_ATTACH_CAPS | KDBUS_ATTACH_CREDS;
1053 b->creds_mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_EFFECTIVE_CAPS;
1055 r = sd_bus_start(b);
1067 int bus_set_address_system(sd_bus *b) {
1071 e = secure_getenv("DBUS_SYSTEM_BUS_ADDRESS");
1073 return sd_bus_set_address(b, e);
1075 return sd_bus_set_address(b, DEFAULT_SYSTEM_BUS_ADDRESS);
1078 _public_ int sd_bus_open_system(sd_bus **ret) {
1082 assert_return(ret, -EINVAL);
1088 r = bus_set_address_system(b);
1092 b->bus_client = true;
1093 b->is_system = true;
1095 /* Let's do per-method access control on the system bus. We
1096 * need the caller's UID and capability set for that. */
1098 b->attach_flags |= KDBUS_ATTACH_CAPS | KDBUS_ATTACH_CREDS;
1099 b->creds_mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_EFFECTIVE_CAPS;
1102 r = sd_bus_start(b);
1114 #if 0 /// elogind can not open/use a user bus
1115 int bus_set_address_user(sd_bus *b) {
1117 _cleanup_free_ char *ee = NULL, *s = NULL;
1121 e = secure_getenv("DBUS_SESSION_BUS_ADDRESS");
1123 return sd_bus_set_address(b, e);
1125 e = secure_getenv("XDG_RUNTIME_DIR");
1129 ee = bus_address_escape(e);
1133 if (asprintf(&s, UNIX_USER_BUS_ADDRESS_FMT, ee) < 0)
1143 _public_ int sd_bus_open_user(sd_bus **ret) {
1144 #if 0 /// elogind does not support user buses
1148 assert_return(ret, -EINVAL);
1154 r = bus_set_address_user(b);
1158 b->bus_client = true;
1161 /* We don't do any per-method access control on the user
1166 r = sd_bus_start(b);
1177 return sd_bus_open_system(ret);
1181 int bus_set_address_system_remote(sd_bus *b, const char *host) {
1182 _cleanup_free_ char *e = NULL;
1183 char *m = NULL, *c = NULL;
1188 /* Let's see if we shall enter some container */
1189 m = strchr(host, ':');
1193 /* Let's make sure this is not a port of some kind,
1194 * and is a valid machine name. */
1195 if (!in_charset(m, "0123456789") && machine_name_is_valid(m)) {
1198 /* Cut out the host part */
1199 t = strndupa(host, m - host - 1);
1200 e = bus_address_escape(t);
1204 c = strjoina(",argv5=--machine=", m);
1209 e = bus_address_escape(host);
1214 b->address = strjoin("unixexec:path=ssh,argv1=-xT,argv2=--,argv3=", e, ",argv4=systemd-stdio-bridge", c);
1221 _public_ int sd_bus_open_system_remote(sd_bus **ret, const char *host) {
1225 assert_return(host, -EINVAL);
1226 assert_return(ret, -EINVAL);
1228 r = sd_bus_new(&bus);
1232 r = bus_set_address_system_remote(bus, host);
1236 bus->bus_client = true;
1237 bus->trusted = false;
1238 bus->is_system = true;
1239 bus->is_local = false;
1241 r = sd_bus_start(bus);
1253 int bus_set_address_system_machine(sd_bus *b, const char *machine) {
1254 _cleanup_free_ char *e = NULL;
1259 e = bus_address_escape(machine);
1263 b->address = strjoin("x-machine-unix:machine=", e);
1270 _public_ int sd_bus_open_system_machine(sd_bus **ret, const char *machine) {
1274 assert_return(machine, -EINVAL);
1275 assert_return(ret, -EINVAL);
1276 assert_return(machine_name_is_valid(machine), -EINVAL);
1278 r = sd_bus_new(&bus);
1282 r = bus_set_address_system_machine(bus, machine);
1286 bus->bus_client = true;
1287 bus->trusted = false;
1288 bus->is_system = true;
1289 bus->is_local = false;
1291 r = sd_bus_start(bus);
1303 _public_ void sd_bus_close(sd_bus *bus) {
1307 if (bus->state == BUS_CLOSED)
1309 if (bus_pid_changed(bus))
1312 bus->state = BUS_CLOSED;
1314 sd_bus_detach_event(bus);
1316 /* Drop all queued messages so that they drop references to
1317 * the bus object and the bus may be freed */
1318 bus_reset_queues(bus);
1323 _public_ sd_bus* sd_bus_flush_close_unref(sd_bus *bus) {
1331 return sd_bus_unref(bus);
1334 static void bus_enter_closing(sd_bus *bus) {
1337 if (!IN_SET(bus->state, BUS_OPENING, BUS_AUTHENTICATING, BUS_HELLO, BUS_RUNNING))
1340 bus->state = BUS_CLOSING;
1343 _public_ sd_bus *sd_bus_ref(sd_bus *bus) {
1348 assert_se(REFCNT_INC(bus->n_ref) >= 2);
1353 _public_ sd_bus *sd_bus_unref(sd_bus *bus) {
1359 i = REFCNT_DEC(bus->n_ref);
1367 _public_ int sd_bus_is_open(sd_bus *bus) {
1369 assert_return(bus, -EINVAL);
1370 assert_return(!bus_pid_changed(bus), -ECHILD);
1372 return BUS_IS_OPEN(bus->state);
1375 _public_ int sd_bus_can_send(sd_bus *bus, char type) {
1378 assert_return(bus, -EINVAL);
1379 assert_return(bus->state != BUS_UNSET, -ENOTCONN);
1380 assert_return(!bus_pid_changed(bus), -ECHILD);
1382 if (bus->hello_flags & KDBUS_HELLO_MONITOR)
1385 if (type == SD_BUS_TYPE_UNIX_FD) {
1386 if (!(bus->hello_flags & KDBUS_HELLO_ACCEPT_FD))
1389 r = bus_ensure_running(bus);
1393 return bus->can_fds;
1396 return bus_type_is_valid(type);
1399 _public_ int sd_bus_get_bus_id(sd_bus *bus, sd_id128_t *id) {
1402 assert_return(bus, -EINVAL);
1403 assert_return(id, -EINVAL);
1404 assert_return(!bus_pid_changed(bus), -ECHILD);
1406 r = bus_ensure_running(bus);
1410 *id = bus->server_id;
1414 static int bus_seal_message(sd_bus *b, sd_bus_message *m, usec_t timeout) {
1419 /* If we copy the same message to multiple
1420 * destinations, avoid using the same cookie
1422 b->cookie = MAX(b->cookie, BUS_MESSAGE_COOKIE(m));
1427 timeout = BUS_DEFAULT_TIMEOUT;
1429 return sd_bus_message_seal(m, ++b->cookie, timeout);
1432 static int bus_remarshal_message(sd_bus *b, sd_bus_message **m) {
1433 bool remarshal = false;
1437 /* wrong packet version */
1438 if (b->message_version != 0 && b->message_version != (*m)->header->version)
1441 /* wrong packet endianness */
1442 if (b->message_endian != 0 && b->message_endian != (*m)->header->endian)
1445 return remarshal ? bus_message_remarshal(b, m) : 0;
1448 int bus_seal_synthetic_message(sd_bus *b, sd_bus_message *m) {
1452 /* Fake some timestamps, if they were requested, and not
1453 * already initialized */
1454 if (b->attach_flags & KDBUS_ATTACH_TIMESTAMP) {
1455 if (m->realtime <= 0)
1456 m->realtime = now(CLOCK_REALTIME);
1458 if (m->monotonic <= 0)
1459 m->monotonic = now(CLOCK_MONOTONIC);
1462 /* The bus specification says the serial number cannot be 0,
1463 * hence let's fill something in for synthetic messages. Since
1464 * synthetic messages might have a fake sender and we don't
1465 * want to interfere with the real sender's serial numbers we
1466 * pick a fixed, artificial one. We use (uint32_t) -1 rather
1467 * than (uint64_t) -1 since dbus1 only had 32bit identifiers,
1468 * even though kdbus can do 64bit. */
1469 return sd_bus_message_seal(m, 0xFFFFFFFFULL, 0);
1472 static int bus_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call, size_t *idx) {
1478 r = bus_socket_write_message(bus, m, idx);
1482 if (*idx >= BUS_MESSAGE_SIZE(m))
1483 log_debug("Sent message type=%s sender=%s destination=%s object=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " error-name=%s error-message=%s",
1484 bus_message_type_to_string(m->header->type),
1485 strna(sd_bus_message_get_sender(m)),
1486 strna(sd_bus_message_get_destination(m)),
1487 strna(sd_bus_message_get_path(m)),
1488 strna(sd_bus_message_get_interface(m)),
1489 strna(sd_bus_message_get_member(m)),
1490 BUS_MESSAGE_COOKIE(m),
1492 strna(m->error.name),
1493 strna(m->error.message));
1498 static int dispatch_wqueue(sd_bus *bus) {
1502 assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO));
1504 while (bus->wqueue_size > 0) {
1506 r = bus_write_message(bus, bus->wqueue[0], false, &bus->windex);
1510 /* Didn't do anything this time */
1512 else if (bus->windex >= BUS_MESSAGE_SIZE(bus->wqueue[0])) {
1513 /* Fully written. Let's drop the entry from
1516 * This isn't particularly optimized, but
1517 * well, this is supposed to be our worst-case
1518 * buffer only, and the socket buffer is
1519 * supposed to be our primary buffer, and if
1520 * it got full, then all bets are off
1524 sd_bus_message_unref(bus->wqueue[0]);
1525 memmove(bus->wqueue, bus->wqueue + 1, sizeof(sd_bus_message*) * bus->wqueue_size);
1535 static int bus_read_message(sd_bus *bus, bool hint_priority, int64_t priority) {
1538 return bus_socket_read_message(bus);
1541 int bus_rqueue_make_room(sd_bus *bus) {
1544 if (bus->rqueue_size >= BUS_RQUEUE_MAX)
1547 if (!GREEDY_REALLOC(bus->rqueue, bus->rqueue_allocated, bus->rqueue_size + 1))
1553 static int dispatch_rqueue(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **m) {
1558 assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO));
1560 /* Note that the priority logic is only available on kdbus,
1561 * where the rqueue is unused. We check the rqueue here
1562 * anyway, because it's simple... */
1565 if (bus->rqueue_size > 0) {
1566 /* Dispatch a queued message */
1568 *m = bus->rqueue[0];
1570 memmove(bus->rqueue, bus->rqueue + 1, sizeof(sd_bus_message*) * bus->rqueue_size);
1574 /* Try to read a new message */
1575 r = bus_read_message(bus, hint_priority, priority);
1585 static int bus_send_internal(sd_bus *bus, sd_bus_message *_m, uint64_t *cookie, bool hint_sync_call) {
1586 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = sd_bus_message_ref(_m);
1589 assert_return(m, -EINVAL);
1594 assert_return(!bus_pid_changed(bus), -ECHILD);
1596 if (!BUS_IS_OPEN(bus->state))
1600 r = sd_bus_can_send(bus, SD_BUS_TYPE_UNIX_FD);
1607 /* If the cookie number isn't kept, then we know that no reply
1609 if (!cookie && !m->sealed)
1610 m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
1612 r = bus_seal_message(bus, m, 0);
1616 /* Remarshall if we have to. This will possibly unref the
1617 * message and place a replacement in m */
1618 r = bus_remarshal_message(bus, &m);
1622 /* If this is a reply and no reply was requested, then let's
1623 * suppress this, if we can */
1627 if (IN_SET(bus->state, BUS_RUNNING, BUS_HELLO) && bus->wqueue_size <= 0) {
1630 r = bus_write_message(bus, m, hint_sync_call, &idx);
1632 if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
1633 bus_enter_closing(bus);
1640 if (idx < BUS_MESSAGE_SIZE(m)) {
1641 /* Wasn't fully written. So let's remember how
1642 * much was written. Note that the first entry
1643 * of the wqueue array is always allocated so
1644 * that we always can remember how much was
1646 bus->wqueue[0] = sd_bus_message_ref(m);
1647 bus->wqueue_size = 1;
1652 /* Just append it to the queue. */
1654 if (bus->wqueue_size >= BUS_WQUEUE_MAX)
1657 if (!GREEDY_REALLOC(bus->wqueue, bus->wqueue_allocated, bus->wqueue_size + 1))
1660 bus->wqueue[bus->wqueue_size++] = sd_bus_message_ref(m);
1665 *cookie = BUS_MESSAGE_COOKIE(m);
1670 _public_ int sd_bus_send(sd_bus *bus, sd_bus_message *m, uint64_t *cookie) {
1671 return bus_send_internal(bus, m, cookie, false);
1674 _public_ int sd_bus_send_to(sd_bus *bus, sd_bus_message *m, const char *destination, uint64_t *cookie) {
1677 assert_return(m, -EINVAL);
1682 assert_return(!bus_pid_changed(bus), -ECHILD);
1684 if (!BUS_IS_OPEN(bus->state))
1687 if (!streq_ptr(m->destination, destination)) {
1692 r = sd_bus_message_set_destination(m, destination);
1697 return sd_bus_send(bus, m, cookie);
1700 static usec_t calc_elapse(uint64_t usec) {
1701 if (usec == (uint64_t) -1)
1704 return now(CLOCK_MONOTONIC) + usec;
1707 static int timeout_compare(const void *a, const void *b) {
1708 const struct reply_callback *x = a, *y = b;
1710 if (x->timeout != 0 && y->timeout == 0)
1713 if (x->timeout == 0 && y->timeout != 0)
1716 if (x->timeout < y->timeout)
1719 if (x->timeout > y->timeout)
1725 _public_ int sd_bus_call_async(
1729 sd_bus_message_handler_t callback,
1733 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = sd_bus_message_ref(_m);
1734 _cleanup_(sd_bus_slot_unrefp) sd_bus_slot *s = NULL;
1737 assert_return(m, -EINVAL);
1738 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
1739 assert_return(!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED), -EINVAL);
1740 assert_return(callback, -EINVAL);
1745 assert_return(!bus_pid_changed(bus), -ECHILD);
1747 if (!BUS_IS_OPEN(bus->state))
1750 r = ordered_hashmap_ensure_allocated(&bus->reply_callbacks, &uint64_hash_ops);
1754 r = prioq_ensure_allocated(&bus->reply_callbacks_prioq, timeout_compare);
1758 r = bus_seal_message(bus, m, usec);
1762 r = bus_remarshal_message(bus, &m);
1766 s = bus_slot_allocate(bus, !slot, BUS_REPLY_CALLBACK, sizeof(struct reply_callback), userdata);
1770 s->reply_callback.callback = callback;
1772 s->reply_callback.cookie = BUS_MESSAGE_COOKIE(m);
1773 r = ordered_hashmap_put(bus->reply_callbacks, &s->reply_callback.cookie, &s->reply_callback);
1775 s->reply_callback.cookie = 0;
1779 s->reply_callback.timeout = calc_elapse(m->timeout);
1780 if (s->reply_callback.timeout != 0) {
1781 r = prioq_put(bus->reply_callbacks_prioq, &s->reply_callback, &s->reply_callback.prioq_idx);
1783 s->reply_callback.timeout = 0;
1788 r = sd_bus_send(bus, m, &s->reply_callback.cookie);
1799 int bus_ensure_running(sd_bus *bus) {
1804 if (IN_SET(bus->state, BUS_UNSET, BUS_CLOSED, BUS_CLOSING))
1806 if (bus->state == BUS_RUNNING)
1810 r = sd_bus_process(bus, NULL);
1813 if (bus->state == BUS_RUNNING)
1818 r = sd_bus_wait(bus, (uint64_t) -1);
1824 _public_ int sd_bus_call(
1828 sd_bus_error *error,
1829 sd_bus_message **reply) {
1831 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = sd_bus_message_ref(_m);
1837 bus_assert_return(m, -EINVAL, error);
1838 bus_assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL, error);
1839 bus_assert_return(!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED), -EINVAL, error);
1840 bus_assert_return(!bus_error_is_dirty(error), -EINVAL, error);
1845 bus_assert_return(!bus_pid_changed(bus), -ECHILD, error);
1847 if (!BUS_IS_OPEN(bus->state)) {
1852 r = bus_ensure_running(bus);
1856 i = bus->rqueue_size;
1858 r = bus_seal_message(bus, m, usec);
1862 r = bus_remarshal_message(bus, &m);
1866 r = bus_send_internal(bus, m, &cookie, true);
1870 timeout = calc_elapse(m->timeout);
1875 while (i < bus->rqueue_size) {
1876 sd_bus_message *incoming = NULL;
1878 incoming = bus->rqueue[i];
1880 if (incoming->reply_cookie == cookie) {
1881 /* Found a match! */
1883 memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1));
1885 log_debug_bus_message(incoming);
1887 if (incoming->header->type == SD_BUS_MESSAGE_METHOD_RETURN) {
1889 if (incoming->n_fds <= 0 || (bus->hello_flags & KDBUS_HELLO_ACCEPT_FD)) {
1893 sd_bus_message_unref(incoming);
1898 r = sd_bus_error_setf(error, SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Reply message contained file descriptors which I couldn't accept. Sorry.");
1899 sd_bus_message_unref(incoming);
1902 } else if (incoming->header->type == SD_BUS_MESSAGE_METHOD_ERROR) {
1903 r = sd_bus_error_copy(error, &incoming->error);
1904 sd_bus_message_unref(incoming);
1911 } else if (BUS_MESSAGE_COOKIE(incoming) == cookie &&
1914 streq(bus->unique_name, incoming->sender)) {
1916 memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1));
1919 /* Our own message? Somebody is trying
1920 * to send its own client a message,
1921 * let's not dead-lock, let's fail
1924 sd_bus_message_unref(incoming);
1929 /* Try to read more, right-away */
1933 r = bus_read_message(bus, false, 0);
1935 if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
1936 bus_enter_closing(bus);
1948 n = now(CLOCK_MONOTONIC);
1956 left = (uint64_t) -1;
1958 r = bus_poll(bus, true, left);
1966 r = dispatch_wqueue(bus);
1968 if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
1969 bus_enter_closing(bus);
1978 return sd_bus_error_set_errno(error, r);
1981 _public_ int sd_bus_get_fd(sd_bus *bus) {
1983 assert_return(bus, -EINVAL);
1984 assert_return(bus->input_fd == bus->output_fd, -EPERM);
1985 assert_return(!bus_pid_changed(bus), -ECHILD);
1987 return bus->input_fd;
1990 _public_ int sd_bus_get_events(sd_bus *bus) {
1993 assert_return(bus, -EINVAL);
1994 assert_return(!bus_pid_changed(bus), -ECHILD);
1996 if (!BUS_IS_OPEN(bus->state) && bus->state != BUS_CLOSING)
1999 if (bus->state == BUS_OPENING)
2001 else if (bus->state == BUS_AUTHENTICATING) {
2003 if (bus_socket_auth_needs_write(bus))
2008 } else if (IN_SET(bus->state, BUS_RUNNING, BUS_HELLO)) {
2009 if (bus->rqueue_size <= 0)
2011 if (bus->wqueue_size > 0)
2018 _public_ int sd_bus_get_timeout(sd_bus *bus, uint64_t *timeout_usec) {
2019 struct reply_callback *c;
2021 assert_return(bus, -EINVAL);
2022 assert_return(timeout_usec, -EINVAL);
2023 assert_return(!bus_pid_changed(bus), -ECHILD);
2025 if (!BUS_IS_OPEN(bus->state) && bus->state != BUS_CLOSING)
2028 if (bus->track_queue) {
2033 if (bus->state == BUS_CLOSING) {
2038 if (bus->state == BUS_AUTHENTICATING) {
2039 *timeout_usec = bus->auth_timeout;
2043 if (!IN_SET(bus->state, BUS_RUNNING, BUS_HELLO)) {
2044 *timeout_usec = (uint64_t) -1;
2048 if (bus->rqueue_size > 0) {
2053 c = prioq_peek(bus->reply_callbacks_prioq);
2055 *timeout_usec = (uint64_t) -1;
2059 if (c->timeout == 0) {
2060 *timeout_usec = (uint64_t) -1;
2064 *timeout_usec = c->timeout;
2068 static int process_timeout(sd_bus *bus) {
2069 _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
2070 _cleanup_(sd_bus_message_unrefp) sd_bus_message* m = NULL;
2071 struct reply_callback *c;
2078 c = prioq_peek(bus->reply_callbacks_prioq);
2082 n = now(CLOCK_MONOTONIC);
2086 r = bus_message_new_synthetic_error(
2089 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out"),
2094 r = bus_seal_synthetic_message(bus, m);
2098 assert_se(prioq_pop(bus->reply_callbacks_prioq) == c);
2101 ordered_hashmap_remove(bus->reply_callbacks, &c->cookie);
2104 slot = container_of(c, sd_bus_slot, reply_callback);
2106 bus->iteration_counter++;
2108 bus->current_message = m;
2109 bus->current_slot = sd_bus_slot_ref(slot);
2110 bus->current_handler = c->callback;
2111 bus->current_userdata = slot->userdata;
2112 r = c->callback(m, slot->userdata, &error_buffer);
2113 bus->current_userdata = NULL;
2114 bus->current_handler = NULL;
2115 bus->current_slot = NULL;
2116 bus->current_message = NULL;
2118 if (slot->floating) {
2119 bus_slot_disconnect(slot);
2120 sd_bus_slot_unref(slot);
2123 sd_bus_slot_unref(slot);
2125 return bus_maybe_reply_error(m, r, &error_buffer);
2128 static int process_hello(sd_bus *bus, sd_bus_message *m) {
2132 if (bus->state != BUS_HELLO)
2135 /* Let's make sure the first message on the bus is the HELLO
2136 * reply. But note that we don't actually parse the message
2137 * here (we leave that to the usual handling), we just verify
2138 * we don't let any earlier msg through. */
2140 if (!IN_SET(m->header->type, SD_BUS_MESSAGE_METHOD_RETURN, SD_BUS_MESSAGE_METHOD_ERROR))
2143 if (m->reply_cookie != 1)
2149 static int process_reply(sd_bus *bus, sd_bus_message *m) {
2150 _cleanup_(sd_bus_message_unrefp) sd_bus_message *synthetic_reply = NULL;
2151 _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
2152 struct reply_callback *c;
2159 if (!IN_SET(m->header->type, SD_BUS_MESSAGE_METHOD_RETURN, SD_BUS_MESSAGE_METHOD_ERROR))
2162 if (m->destination && bus->unique_name && !streq_ptr(m->destination, bus->unique_name))
2165 c = ordered_hashmap_remove(bus->reply_callbacks, &m->reply_cookie);
2171 slot = container_of(c, sd_bus_slot, reply_callback);
2173 if (m->n_fds > 0 && !(bus->hello_flags & KDBUS_HELLO_ACCEPT_FD)) {
2175 /* If the reply contained a file descriptor which we
2176 * didn't want we pass an error instead. */
2178 r = bus_message_new_synthetic_error(
2181 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Reply message contained file descriptor"),
2186 /* Copy over original timestamp */
2187 synthetic_reply->realtime = m->realtime;
2188 synthetic_reply->monotonic = m->monotonic;
2189 synthetic_reply->seqnum = m->seqnum;
2191 r = bus_seal_synthetic_message(bus, synthetic_reply);
2195 m = synthetic_reply;
2197 r = sd_bus_message_rewind(m, true);
2202 if (c->timeout != 0) {
2203 prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
2207 bus->current_slot = sd_bus_slot_ref(slot);
2208 bus->current_handler = c->callback;
2209 bus->current_userdata = slot->userdata;
2210 r = c->callback(m, slot->userdata, &error_buffer);
2211 bus->current_userdata = NULL;
2212 bus->current_handler = NULL;
2213 bus->current_slot = NULL;
2215 if (slot->floating) {
2216 bus_slot_disconnect(slot);
2217 sd_bus_slot_unref(slot);
2220 sd_bus_slot_unref(slot);
2222 return bus_maybe_reply_error(m, r, &error_buffer);
2225 static int process_filter(sd_bus *bus, sd_bus_message *m) {
2226 _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
2227 struct filter_callback *l;
2234 bus->filter_callbacks_modified = false;
2236 LIST_FOREACH(callbacks, l, bus->filter_callbacks) {
2239 if (bus->filter_callbacks_modified)
2242 /* Don't run this more than once per iteration */
2243 if (l->last_iteration == bus->iteration_counter)
2246 l->last_iteration = bus->iteration_counter;
2248 r = sd_bus_message_rewind(m, true);
2252 slot = container_of(l, sd_bus_slot, filter_callback);
2254 bus->current_slot = sd_bus_slot_ref(slot);
2255 bus->current_handler = l->callback;
2256 bus->current_userdata = slot->userdata;
2257 r = l->callback(m, slot->userdata, &error_buffer);
2258 bus->current_userdata = NULL;
2259 bus->current_handler = NULL;
2260 bus->current_slot = sd_bus_slot_unref(slot);
2262 r = bus_maybe_reply_error(m, r, &error_buffer);
2268 } while (bus->filter_callbacks_modified);
2273 static int process_match(sd_bus *bus, sd_bus_message *m) {
2280 bus->match_callbacks_modified = false;
2282 r = bus_match_run(bus, &bus->match_callbacks, m);
2286 } while (bus->match_callbacks_modified);
2291 static int process_builtin(sd_bus *bus, sd_bus_message *m) {
2292 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
2298 if (bus->hello_flags & KDBUS_HELLO_MONITOR)
2301 if (bus->manual_peer_interface)
2304 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
2307 if (!streq_ptr(m->interface, "org.freedesktop.DBus.Peer"))
2310 if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
2313 if (streq_ptr(m->member, "Ping"))
2314 r = sd_bus_message_new_method_return(m, &reply);
2315 else if (streq_ptr(m->member, "GetMachineId")) {
2319 r = sd_id128_get_machine(&id);
2323 r = sd_bus_message_new_method_return(m, &reply);
2327 r = sd_bus_message_append(reply, "s", sd_id128_to_string(id, sid));
2329 r = sd_bus_message_new_method_errorf(
2331 SD_BUS_ERROR_UNKNOWN_METHOD,
2332 "Unknown method '%s' on interface '%s'.", m->member, m->interface);
2338 r = sd_bus_send(bus, reply, NULL);
2345 static int process_fd_check(sd_bus *bus, sd_bus_message *m) {
2349 /* If we got a message with a file descriptor which we didn't
2350 * want to accept, then let's drop it. How can this even
2351 * happen? For example, when the kernel queues a message into
2352 * an activatable names's queue which allows fds, and then is
2353 * delivered to us later even though we ourselves did not
2356 if (bus->hello_flags & KDBUS_HELLO_MONITOR)
2362 if (bus->hello_flags & KDBUS_HELLO_ACCEPT_FD)
2365 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
2366 return 1; /* just eat it up */
2368 return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Message contains file descriptors, which I cannot accept. Sorry.");
2371 static int process_message(sd_bus *bus, sd_bus_message *m) {
2377 bus->current_message = m;
2378 bus->iteration_counter++;
2380 log_debug_bus_message(m);
2382 r = process_hello(bus, m);
2386 r = process_reply(bus, m);
2390 r = process_fd_check(bus, m);
2394 r = process_filter(bus, m);
2398 r = process_match(bus, m);
2402 r = process_builtin(bus, m);
2406 r = bus_process_object(bus, m);
2409 bus->current_message = NULL;
2413 static int dispatch_track(sd_bus *bus) {
2416 if (!bus->track_queue)
2419 bus_track_dispatch(bus->track_queue);
2423 static int process_running(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **ret) {
2424 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
2428 assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO));
2430 r = process_timeout(bus);
2434 r = dispatch_wqueue(bus);
2438 r = dispatch_track(bus);
2442 r = dispatch_rqueue(bus, hint_priority, priority, &m);
2448 r = process_message(bus, m);
2453 r = sd_bus_message_rewind(m, true);
2462 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL) {
2464 log_debug("Unprocessed message call sender=%s object=%s interface=%s member=%s",
2465 strna(sd_bus_message_get_sender(m)),
2466 strna(sd_bus_message_get_path(m)),
2467 strna(sd_bus_message_get_interface(m)),
2468 strna(sd_bus_message_get_member(m)));
2470 r = sd_bus_reply_method_errorf(
2472 SD_BUS_ERROR_UNKNOWN_OBJECT,
2473 "Unknown object '%s'.", m->path);
2487 static int bus_exit_now(sd_bus *bus) {
2490 /* Exit due to close, if this is requested. If this is bus object is attached to an event source, invokes
2491 * sd_event_exit(), otherwise invokes libc exit(). */
2493 if (bus->exited) /* did we already exit? */
2495 if (!bus->exit_triggered) /* was the exit condition triggered? */
2497 if (!bus->exit_on_disconnect) /* Shall we actually exit on disconnection? */
2500 bus->exited = true; /* never exit more than once */
2502 log_debug("Bus connection disconnected, exiting.");
2505 return sd_event_exit(bus->event, EXIT_FAILURE);
2509 assert_not_reached("exit() didn't exit?");
2512 static int process_closing_reply_callback(sd_bus *bus, struct reply_callback *c) {
2513 _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
2514 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
2521 r = bus_message_new_synthetic_error(
2524 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Connection terminated"),
2529 r = bus_seal_synthetic_message(bus, m);
2533 if (c->timeout != 0) {
2534 prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
2538 ordered_hashmap_remove(bus->reply_callbacks, &c->cookie);
2541 slot = container_of(c, sd_bus_slot, reply_callback);
2543 bus->iteration_counter++;
2545 bus->current_message = m;
2546 bus->current_slot = sd_bus_slot_ref(slot);
2547 bus->current_handler = c->callback;
2548 bus->current_userdata = slot->userdata;
2549 r = c->callback(m, slot->userdata, &error_buffer);
2550 bus->current_userdata = NULL;
2551 bus->current_handler = NULL;
2552 bus->current_slot = NULL;
2553 bus->current_message = NULL;
2555 if (slot->floating) {
2556 bus_slot_disconnect(slot);
2557 sd_bus_slot_unref(slot);
2560 sd_bus_slot_unref(slot);
2562 return bus_maybe_reply_error(m, r, &error_buffer);
2565 static int process_closing(sd_bus *bus, sd_bus_message **ret) {
2566 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
2567 struct reply_callback *c;
2571 assert(bus->state == BUS_CLOSING);
2573 /* First, fail all outstanding method calls */
2574 c = ordered_hashmap_first(bus->reply_callbacks);
2576 return process_closing_reply_callback(bus, c);
2578 /* Then, fake-drop all remaining bus tracking references */
2580 bus_track_close(bus->tracks);
2584 /* Then, synthesize a Disconnected message */
2585 r = sd_bus_message_new_signal(
2588 "/org/freedesktop/DBus/Local",
2589 "org.freedesktop.DBus.Local",
2594 bus_message_set_sender_local(bus, m);
2596 r = bus_seal_synthetic_message(bus, m);
2602 bus->current_message = m;
2603 bus->iteration_counter++;
2605 r = process_filter(bus, m);
2609 r = process_match(bus, m);
2613 /* Nothing else to do, exit now, if the condition holds */
2614 bus->exit_triggered = true;
2615 (void) bus_exit_now(bus);
2625 bus->current_message = NULL;
2630 static int bus_process_internal(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **ret) {
2631 BUS_DONT_DESTROY(bus);
2634 /* Returns 0 when we didn't do anything. This should cause the
2635 * caller to invoke sd_bus_wait() before returning the next
2636 * time. Returns > 0 when we did something, which possibly
2637 * means *ret is filled in with an unprocessed message. */
2639 assert_return(bus, -EINVAL);
2640 assert_return(!bus_pid_changed(bus), -ECHILD);
2642 /* We don't allow recursively invoking sd_bus_process(). */
2643 assert_return(!bus->current_message, -EBUSY);
2644 assert(!bus->current_slot);
2646 switch (bus->state) {
2655 r = bus_socket_process_opening(bus);
2656 if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
2657 bus_enter_closing(bus);
2665 case BUS_AUTHENTICATING:
2666 r = bus_socket_process_authenticating(bus);
2667 if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
2668 bus_enter_closing(bus);
2680 r = process_running(bus, hint_priority, priority, ret);
2681 if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
2682 bus_enter_closing(bus);
2692 return process_closing(bus, ret);
2695 assert_not_reached("Unknown state");
2698 _public_ int sd_bus_process(sd_bus *bus, sd_bus_message **ret) {
2699 return bus_process_internal(bus, false, 0, ret);
2702 _public_ int sd_bus_process_priority(sd_bus *bus, int64_t priority, sd_bus_message **ret) {
2703 return bus_process_internal(bus, true, priority, ret);
2706 static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec) {
2707 struct pollfd p[2] = {};
2710 usec_t m = USEC_INFINITY;
2714 if (bus->state == BUS_CLOSING)
2717 if (!BUS_IS_OPEN(bus->state))
2720 e = sd_bus_get_events(bus);
2725 /* The caller really needs some more data, he doesn't
2726 * care about what's already read, or any timeouts
2727 * except its own. */
2731 /* The caller wants to process if there's something to
2732 * process, but doesn't care otherwise */
2734 r = sd_bus_get_timeout(bus, &until);
2739 nw = now(CLOCK_MONOTONIC);
2740 m = until > nw ? until - nw : 0;
2744 if (timeout_usec != (uint64_t) -1 && (m == (uint64_t) -1 || timeout_usec < m))
2747 p[0].fd = bus->input_fd;
2748 if (bus->output_fd == bus->input_fd) {
2752 p[0].events = e & POLLIN;
2753 p[1].fd = bus->output_fd;
2754 p[1].events = e & POLLOUT;
2758 r = ppoll(p, n, m == (uint64_t) -1 ? NULL : timespec_store(&ts, m), NULL);
2762 return r > 0 ? 1 : 0;
2765 _public_ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) {
2767 assert_return(bus, -EINVAL);
2768 assert_return(!bus_pid_changed(bus), -ECHILD);
2770 if (bus->state == BUS_CLOSING)
2773 if (!BUS_IS_OPEN(bus->state))
2776 if (bus->rqueue_size > 0)
2779 return bus_poll(bus, false, timeout_usec);
2782 _public_ int sd_bus_flush(sd_bus *bus) {
2785 assert_return(bus, -EINVAL);
2786 assert_return(!bus_pid_changed(bus), -ECHILD);
2788 if (bus->state == BUS_CLOSING)
2791 if (!BUS_IS_OPEN(bus->state))
2794 r = bus_ensure_running(bus);
2798 if (bus->wqueue_size <= 0)
2802 r = dispatch_wqueue(bus);
2804 if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
2805 bus_enter_closing(bus);
2812 if (bus->wqueue_size <= 0)
2815 r = bus_poll(bus, false, (uint64_t) -1);
2821 _public_ int sd_bus_add_filter(
2824 sd_bus_message_handler_t callback,
2829 assert_return(bus, -EINVAL);
2830 assert_return(callback, -EINVAL);
2831 assert_return(!bus_pid_changed(bus), -ECHILD);
2833 s = bus_slot_allocate(bus, !slot, BUS_FILTER_CALLBACK, sizeof(struct filter_callback), userdata);
2837 s->filter_callback.callback = callback;
2839 bus->filter_callbacks_modified = true;
2840 LIST_PREPEND(callbacks, bus->filter_callbacks, &s->filter_callback);
2848 _public_ int sd_bus_add_match(
2852 sd_bus_message_handler_t callback,
2855 struct bus_match_component *components = NULL;
2856 unsigned n_components = 0;
2857 sd_bus_slot *s = NULL;
2860 assert_return(bus, -EINVAL);
2861 assert_return(match, -EINVAL);
2862 assert_return(!bus_pid_changed(bus), -ECHILD);
2864 r = bus_match_parse(match, &components, &n_components);
2868 s = bus_slot_allocate(bus, !slot, BUS_MATCH_CALLBACK, sizeof(struct match_callback), userdata);
2874 s->match_callback.callback = callback;
2876 if (bus->bus_client) {
2877 enum bus_match_scope scope;
2879 scope = bus_match_get_scope(components, n_components);
2881 /* Do not install server-side matches for matches
2882 * against the local service, interface or bus path. */
2883 if (scope != BUS_MATCH_LOCAL) {
2885 /* We store the original match string, so that
2886 * we can use it to remove the match again. */
2888 s->match_callback.match_string = strdup(match);
2889 if (!s->match_callback.match_string) {
2894 r = bus_add_match_internal(bus, s->match_callback.match_string, components, n_components);
2898 s->match_added = true;
2902 bus->match_callbacks_modified = true;
2903 r = bus_match_add(&bus->match_callbacks, components, n_components, &s->match_callback);
2912 bus_match_parse_free(components, n_components);
2913 sd_bus_slot_unref(s);
2918 #if 0 /// UNNEEDED by elogind
2919 int bus_remove_match_by_string(
2922 sd_bus_message_handler_t callback,
2925 struct bus_match_component *components = NULL;
2926 unsigned n_components = 0;
2927 struct match_callback *c;
2930 assert_return(bus, -EINVAL);
2931 assert_return(match, -EINVAL);
2932 assert_return(!bus_pid_changed(bus), -ECHILD);
2934 r = bus_match_parse(match, &components, &n_components);
2938 r = bus_match_find(&bus->match_callbacks, components, n_components, NULL, NULL, &c);
2942 sd_bus_slot_unref(container_of(c, sd_bus_slot, match_callback));
2945 bus_match_parse_free(components, n_components);
2951 bool bus_pid_changed(sd_bus *bus) {
2954 /* We don't support people creating a bus connection and
2955 * keeping it around over a fork(). Let's complain. */
2957 return bus->original_pid != getpid_cached();
2960 static int io_callback(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
2961 sd_bus *bus = userdata;
2966 r = sd_bus_process(bus, NULL);
2973 static int time_callback(sd_event_source *s, uint64_t usec, void *userdata) {
2974 sd_bus *bus = userdata;
2979 r = sd_bus_process(bus, NULL);
2986 static int prepare_callback(sd_event_source *s, void *userdata) {
2987 sd_bus *bus = userdata;
2994 e = sd_bus_get_events(bus);
2998 if (bus->output_fd != bus->input_fd) {
3000 r = sd_event_source_set_io_events(bus->input_io_event_source, e & POLLIN);
3004 r = sd_event_source_set_io_events(bus->output_io_event_source, e & POLLOUT);
3008 r = sd_event_source_set_io_events(bus->input_io_event_source, e);
3013 r = sd_bus_get_timeout(bus, &until);
3019 j = sd_event_source_set_time(bus->time_event_source, until);
3024 r = sd_event_source_set_enabled(bus->time_event_source, r > 0);
3031 static int quit_callback(sd_event_source *event, void *userdata) {
3032 sd_bus *bus = userdata;
3042 static int attach_io_events(sd_bus *bus) {
3047 if (bus->input_fd < 0)
3053 if (!bus->input_io_event_source) {
3054 r = sd_event_add_io(bus->event, &bus->input_io_event_source, bus->input_fd, 0, io_callback, bus);
3058 r = sd_event_source_set_prepare(bus->input_io_event_source, prepare_callback);
3062 r = sd_event_source_set_priority(bus->input_io_event_source, bus->event_priority);
3066 r = sd_event_source_set_description(bus->input_io_event_source, "bus-input");
3068 r = sd_event_source_set_io_fd(bus->input_io_event_source, bus->input_fd);
3073 if (bus->output_fd != bus->input_fd) {
3074 assert(bus->output_fd >= 0);
3076 if (!bus->output_io_event_source) {
3077 r = sd_event_add_io(bus->event, &bus->output_io_event_source, bus->output_fd, 0, io_callback, bus);
3081 r = sd_event_source_set_priority(bus->output_io_event_source, bus->event_priority);
3085 r = sd_event_source_set_description(bus->input_io_event_source, "bus-output");
3087 r = sd_event_source_set_io_fd(bus->output_io_event_source, bus->output_fd);
3096 static void detach_io_events(sd_bus *bus) {
3099 if (bus->input_io_event_source) {
3100 sd_event_source_set_enabled(bus->input_io_event_source, SD_EVENT_OFF);
3101 bus->input_io_event_source = sd_event_source_unref(bus->input_io_event_source);
3104 if (bus->output_io_event_source) {
3105 sd_event_source_set_enabled(bus->output_io_event_source, SD_EVENT_OFF);
3106 bus->output_io_event_source = sd_event_source_unref(bus->output_io_event_source);
3110 _public_ int sd_bus_attach_event(sd_bus *bus, sd_event *event, int priority) {
3113 assert_return(bus, -EINVAL);
3114 assert_return(!bus->event, -EBUSY);
3116 assert(!bus->input_io_event_source);
3117 assert(!bus->output_io_event_source);
3118 assert(!bus->time_event_source);
3121 bus->event = sd_event_ref(event);
3123 r = sd_event_default(&bus->event);
3128 bus->event_priority = priority;
3130 r = sd_event_add_time(bus->event, &bus->time_event_source, CLOCK_MONOTONIC, 0, 0, time_callback, bus);
3134 r = sd_event_source_set_priority(bus->time_event_source, priority);
3138 r = sd_event_source_set_description(bus->time_event_source, "bus-time");
3142 r = sd_event_add_exit(bus->event, &bus->quit_event_source, quit_callback, bus);
3146 r = sd_event_source_set_description(bus->quit_event_source, "bus-exit");
3150 r = attach_io_events(bus);
3157 sd_bus_detach_event(bus);
3161 _public_ int sd_bus_detach_event(sd_bus *bus) {
3162 assert_return(bus, -EINVAL);
3167 detach_io_events(bus);
3169 if (bus->time_event_source) {
3170 sd_event_source_set_enabled(bus->time_event_source, SD_EVENT_OFF);
3171 bus->time_event_source = sd_event_source_unref(bus->time_event_source);
3174 if (bus->quit_event_source) {
3175 sd_event_source_set_enabled(bus->quit_event_source, SD_EVENT_OFF);
3176 bus->quit_event_source = sd_event_source_unref(bus->quit_event_source);
3179 bus->event = sd_event_unref(bus->event);
3183 _public_ sd_event* sd_bus_get_event(sd_bus *bus) {
3184 assert_return(bus, NULL);
3189 _public_ sd_bus_message* sd_bus_get_current_message(sd_bus *bus) {
3190 assert_return(bus, NULL);
3192 return bus->current_message;
3195 _public_ sd_bus_slot* sd_bus_get_current_slot(sd_bus *bus) {
3196 assert_return(bus, NULL);
3198 return bus->current_slot;
3201 _public_ sd_bus_message_handler_t sd_bus_get_current_handler(sd_bus *bus) {
3202 assert_return(bus, NULL);
3204 return bus->current_handler;
3207 _public_ void* sd_bus_get_current_userdata(sd_bus *bus) {
3208 assert_return(bus, NULL);
3210 return bus->current_userdata;
3213 static int bus_default(int (*bus_open)(sd_bus **), sd_bus **default_bus, sd_bus **ret) {
3218 assert(default_bus);
3221 return !!*default_bus;
3224 *ret = sd_bus_ref(*default_bus);
3232 b->default_bus_ptr = default_bus;
3240 _public_ int sd_bus_default_system(sd_bus **ret) {
3241 return bus_default(sd_bus_open_system, &default_system_bus, ret);
3245 _public_ int sd_bus_default_user(sd_bus **ret) {
3246 #if 0 /// elogind does not support user buses
3247 return bus_default(sd_bus_open_user, &default_user_bus, ret);
3249 return sd_bus_default_system(ret);
3253 _public_ int sd_bus_default(sd_bus **ret) {
3257 /* Let's try our best to reuse another cached connection. If
3258 * the starter bus type is set, connect via our normal
3259 * connection logic, ignoring $DBUS_STARTER_ADDRESS, so that
3260 * we can share the connection with the user/system default
3263 e = secure_getenv("DBUS_STARTER_BUS_TYPE");
3265 if (streq(e, "system"))
3266 return sd_bus_default_system(ret);
3267 #if 0 /// elogind does not support systemd units
3268 else if (STR_IN_SET(e, "user", "session"))
3269 return sd_bus_default_user(ret);
3273 /* No type is specified, so we have not other option than to
3274 * use the starter address if it is set. */
3276 e = secure_getenv("DBUS_STARTER_ADDRESS");
3279 return bus_default(sd_bus_open, &default_starter_bus, ret);
3282 /* Finally, if nothing is set use the cached connection for
3283 * the right scope */
3285 #if 0 /// elogind does not support systemd user instances
3286 if (cg_pid_get_owner_uid(0, NULL) >= 0)
3287 return sd_bus_default_user(ret);
3290 return sd_bus_default_system(ret);
3293 _public_ int sd_bus_get_tid(sd_bus *b, pid_t *tid) {
3294 assert_return(b, -EINVAL);
3295 assert_return(tid, -EINVAL);
3296 assert_return(!bus_pid_changed(b), -ECHILD);
3304 return sd_event_get_tid(b->event, tid);
3309 _public_ int sd_bus_path_encode(const char *prefix, const char *external_id, char **ret_path) {
3310 _cleanup_free_ char *e = NULL;
3313 assert_return(object_path_is_valid(prefix), -EINVAL);
3314 assert_return(external_id, -EINVAL);
3315 assert_return(ret_path, -EINVAL);
3317 e = bus_label_escape(external_id);
3321 ret = strjoin(prefix, "/", e);
3329 _public_ int sd_bus_path_decode(const char *path, const char *prefix, char **external_id) {
3333 assert_return(object_path_is_valid(path), -EINVAL);
3334 assert_return(object_path_is_valid(prefix), -EINVAL);
3335 assert_return(external_id, -EINVAL);
3337 e = object_path_startswith(path, prefix);
3339 *external_id = NULL;
3343 ret = bus_label_unescape(e);
3351 _public_ int sd_bus_path_encode_many(char **out, const char *path_template, ...) {
3352 _cleanup_strv_free_ char **labels = NULL;
3353 char *path, *path_pos, **label_pos;
3354 const char *sep, *template_pos;
3359 assert_return(out, -EINVAL);
3360 assert_return(path_template, -EINVAL);
3362 path_length = strlen(path_template);
3364 va_start(list, path_template);
3365 for (sep = strchr(path_template, '%'); sep; sep = strchr(sep + 1, '%')) {
3369 arg = va_arg(list, const char *);
3375 label = bus_label_escape(arg);
3381 r = strv_consume(&labels, label);
3387 /* add label length, but account for the format character */
3388 path_length += strlen(label) - 1;
3392 path = malloc(path_length + 1);
3399 for (template_pos = path_template; *template_pos; ) {
3400 sep = strchrnul(template_pos, '%');
3401 path_pos = mempcpy(path_pos, template_pos, sep - template_pos);
3405 path_pos = stpcpy(path_pos, *label_pos++);
3406 template_pos = sep + 1;
3414 _public_ int sd_bus_path_decode_many(const char *path, const char *path_template, ...) {
3415 _cleanup_strv_free_ char **labels = NULL;
3416 const char *template_pos, *path_pos;
3422 * This decodes an object-path based on a template argument. The
3423 * template consists of a verbatim path, optionally including special
3426 * - Each occurrence of '%' in the template matches an arbitrary
3427 * substring of a label in the given path. At most one such
3428 * directive is allowed per label. For each such directive, the
3429 * caller must provide an output parameter (char **) via va_arg. If
3430 * NULL is passed, the given label is verified, but not returned.
3431 * For each matched label, the *decoded* label is stored in the
3432 * passed output argument, and the caller is responsible to free
3433 * it. Note that the output arguments are only modified if the
3434 * actualy path matched the template. Otherwise, they're left
3437 * This function returns <0 on error, 0 if the path does not match the
3438 * template, 1 if it matched.
3441 assert_return(path, -EINVAL);
3442 assert_return(path_template, -EINVAL);
3446 for (template_pos = path_template; *template_pos; ) {
3451 /* verify everything until the next '%' matches verbatim */
3452 sep = strchrnul(template_pos, '%');
3453 length = sep - template_pos;
3454 if (strncmp(path_pos, template_pos, length))
3458 template_pos += length;
3463 /* We found the next '%' character. Everything up until here
3464 * matched. We now skip ahead to the end of this label and make
3465 * sure it matches the tail of the label in the path. Then we
3466 * decode the string in-between and save it for later use. */
3468 ++template_pos; /* skip over '%' */
3470 sep = strchrnul(template_pos, '/');
3471 length = sep - template_pos; /* length of suffix to match verbatim */
3473 /* verify the suffixes match */
3474 sep = strchrnul(path_pos, '/');
3475 if (sep - path_pos < (ssize_t)length ||
3476 strncmp(sep - length, template_pos, length))
3479 template_pos += length; /* skip over matched label */
3480 length = sep - path_pos - length; /* length of sub-label to decode */
3482 /* store unescaped label for later use */
3483 label = bus_label_unescape_n(path_pos, length);
3487 r = strv_consume(&labels, label);
3491 path_pos = sep; /* skip decoded label and suffix */
3494 /* end of template must match end of path */
3498 /* copy the labels over to the caller */
3499 va_start(list, path_template);
3500 for (label_pos = labels; label_pos && *label_pos; ++label_pos) {
3503 arg = va_arg(list, char **);
3516 _public_ int sd_bus_try_close(sd_bus *bus) {
3517 assert_return(bus, -EINVAL);
3518 assert_return(!bus_pid_changed(bus), -ECHILD);
3523 _public_ int sd_bus_get_description(sd_bus *bus, const char **description) {
3524 assert_return(bus, -EINVAL);
3525 assert_return(description, -EINVAL);
3526 assert_return(bus->description, -ENXIO);
3527 assert_return(!bus_pid_changed(bus), -ECHILD);
3529 *description = bus->description;
3533 int bus_get_root_path(sd_bus *bus) {
3536 if (bus->cgroup_root)
3539 r = cg_get_root_path(&bus->cgroup_root);
3541 bus->cgroup_root = strdup("/");
3542 if (!bus->cgroup_root)
3551 _public_ int sd_bus_get_scope(sd_bus *bus, const char **scope) {
3552 assert_return(bus, -EINVAL);
3553 assert_return(scope, -EINVAL);
3554 assert_return(!bus_pid_changed(bus), -ECHILD);
3561 if (bus->is_system) {
3569 _public_ int sd_bus_get_address(sd_bus *bus, const char **address) {
3571 assert_return(bus, -EINVAL);
3572 assert_return(address, -EINVAL);
3573 assert_return(!bus_pid_changed(bus), -ECHILD);
3576 *address = bus->address;
3583 _public_ int sd_bus_get_creds_mask(sd_bus *bus, uint64_t *mask) {
3584 assert_return(bus, -EINVAL);
3585 assert_return(mask, -EINVAL);
3586 assert_return(!bus_pid_changed(bus), -ECHILD);
3588 *mask = bus->creds_mask;
3592 _public_ int sd_bus_is_bus_client(sd_bus *bus) {
3593 assert_return(bus, -EINVAL);
3594 assert_return(!bus_pid_changed(bus), -ECHILD);
3596 return bus->bus_client;
3599 _public_ int sd_bus_is_server(sd_bus *bus) {
3600 assert_return(bus, -EINVAL);
3601 assert_return(!bus_pid_changed(bus), -ECHILD);
3603 return bus->is_server;
3606 _public_ int sd_bus_is_anonymous(sd_bus *bus) {
3607 assert_return(bus, -EINVAL);
3608 assert_return(!bus_pid_changed(bus), -ECHILD);
3610 return bus->anonymous_auth;
3613 _public_ int sd_bus_is_trusted(sd_bus *bus) {
3614 assert_return(bus, -EINVAL);
3615 assert_return(!bus_pid_changed(bus), -ECHILD);
3617 return bus->trusted;
3620 _public_ int sd_bus_is_monitor(sd_bus *bus) {
3621 assert_return(bus, -EINVAL);
3622 assert_return(!bus_pid_changed(bus), -ECHILD);
3624 return !!(bus->hello_flags & KDBUS_HELLO_MONITOR);
3627 static void flush_close(sd_bus *bus) {
3631 /* Flushes and closes the specified bus. We take a ref before,
3632 * to ensure the flushing does not cause the bus to be
3635 sd_bus_flush_close_unref(sd_bus_ref(bus));
3638 _public_ void sd_bus_default_flush_close(void) {
3639 flush_close(default_starter_bus);
3640 #if 0 /// elogind does not support user buses
3641 flush_close(default_user_bus);
3643 flush_close(default_system_bus);
3646 _public_ int sd_bus_set_exit_on_disconnect(sd_bus *bus, int b) {
3647 assert_return(bus, -EINVAL);
3649 /* Turns on exit-on-disconnect, and triggers it immediately if the bus connection was already
3650 * disconnected. Note that this is triggered exclusively on disconnections triggered by the server side, never
3651 * from the client side. */
3652 bus->exit_on_disconnect = b;
3654 /* If the exit condition was triggered already, exit immediately. */
3655 return bus_exit_now(bus);
3658 _public_ int sd_bus_get_exit_on_disconnect(sd_bus *bus) {
3659 assert_return(bus, -EINVAL);
3661 return bus->exit_on_disconnect;