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 path=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " signature=%s 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->root_container.signature), \
73 strna(_mm->error.name), \
74 strna(_mm->error.message)); \
77 static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec);
78 static int attach_io_events(sd_bus *b);
79 static void detach_io_events(sd_bus *b);
81 static thread_local sd_bus *default_system_bus = NULL;
82 #if 0 /// UNNEEDED by elogind
83 static thread_local sd_bus *default_user_bus = NULL;
85 static thread_local sd_bus *default_starter_bus = NULL;
87 static void bus_close_fds(sd_bus *b) {
92 if (b->input_fd != b->output_fd)
93 safe_close(b->output_fd);
94 b->output_fd = b->input_fd = safe_close(b->input_fd);
97 static void bus_reset_queues(sd_bus *b) {
100 while (b->rqueue_size > 0)
101 sd_bus_message_unref(b->rqueue[--b->rqueue_size]);
103 b->rqueue = mfree(b->rqueue);
104 b->rqueue_allocated = 0;
106 while (b->wqueue_size > 0)
107 sd_bus_message_unref(b->wqueue[--b->wqueue_size]);
109 b->wqueue = mfree(b->wqueue);
110 b->wqueue_allocated = 0;
113 static void bus_free(sd_bus *b) {
117 assert(!b->track_queue);
120 b->state = BUS_CLOSED;
122 sd_bus_detach_event(b);
124 while ((s = b->slots)) {
125 /* At this point only floating slots can still be
126 * around, because the non-floating ones keep a
127 * reference to the bus, and we thus couldn't be
128 * destructing right now... We forcibly disconnect the
129 * slots here, so that they still can be referenced by
130 * apps, but are dead. */
133 bus_slot_disconnect(s);
134 sd_bus_slot_unref(s);
137 if (b->default_bus_ptr)
138 *b->default_bus_ptr = NULL;
145 free(b->unique_name);
146 free(b->auth_buffer);
149 free(b->cgroup_root);
150 free(b->description);
153 strv_free(b->exec_argv);
155 close_many(b->fds, b->n_fds);
160 ordered_hashmap_free_free(b->reply_callbacks);
161 prioq_free(b->reply_callbacks_prioq);
163 assert(b->match_callbacks.type == BUS_MATCH_ROOT);
164 bus_match_free(&b->match_callbacks);
166 hashmap_free_free(b->vtable_methods);
167 hashmap_free_free(b->vtable_properties);
169 assert(hashmap_isempty(b->nodes));
170 hashmap_free(b->nodes);
174 assert_se(pthread_mutex_destroy(&b->memfd_cache_mutex) == 0);
179 _public_ int sd_bus_new(sd_bus **ret) {
182 assert_return(ret, -EINVAL);
188 r->n_ref = REFCNT_INIT;
189 r->input_fd = r->output_fd = -1;
190 r->message_version = 1;
191 r->creds_mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME;
192 r->hello_flags |= KDBUS_HELLO_ACCEPT_FD;
193 r->attach_flags |= KDBUS_ATTACH_NAMES;
194 r->original_pid = getpid_cached();
195 r->n_groups = (size_t) -1;
197 assert_se(pthread_mutex_init(&r->memfd_cache_mutex, NULL) == 0);
199 /* We guarantee that wqueue always has space for at least one
201 if (!GREEDY_REALLOC(r->wqueue, r->wqueue_allocated, 1)) {
210 _public_ int sd_bus_set_address(sd_bus *bus, const char *address) {
213 assert_return(bus, -EINVAL);
214 assert_return(bus->state == BUS_UNSET, -EPERM);
215 assert_return(address, -EINVAL);
216 assert_return(!bus_pid_changed(bus), -ECHILD);
228 _public_ int sd_bus_set_fd(sd_bus *bus, int input_fd, int output_fd) {
229 assert_return(bus, -EINVAL);
230 assert_return(bus->state == BUS_UNSET, -EPERM);
231 assert_return(input_fd >= 0, -EBADF);
232 assert_return(output_fd >= 0, -EBADF);
233 assert_return(!bus_pid_changed(bus), -ECHILD);
235 bus->input_fd = input_fd;
236 bus->output_fd = output_fd;
240 _public_ int sd_bus_set_exec(sd_bus *bus, const char *path, char *const argv[]) {
243 assert_return(bus, -EINVAL);
244 assert_return(bus->state == BUS_UNSET, -EPERM);
245 assert_return(path, -EINVAL);
246 assert_return(!strv_isempty(argv), -EINVAL);
247 assert_return(!bus_pid_changed(bus), -ECHILD);
259 free(bus->exec_path);
260 strv_free(bus->exec_argv);
268 _public_ int sd_bus_set_bus_client(sd_bus *bus, int b) {
269 assert_return(bus, -EINVAL);
270 assert_return(bus->state == BUS_UNSET, -EPERM);
271 assert_return(!bus_pid_changed(bus), -ECHILD);
273 bus->bus_client = !!b;
277 _public_ int sd_bus_set_monitor(sd_bus *bus, int b) {
278 assert_return(bus, -EINVAL);
279 assert_return(bus->state == BUS_UNSET, -EPERM);
280 assert_return(!bus_pid_changed(bus), -ECHILD);
282 SET_FLAG(bus->hello_flags, KDBUS_HELLO_MONITOR, b);
286 _public_ int sd_bus_negotiate_fds(sd_bus *bus, int b) {
287 assert_return(bus, -EINVAL);
288 assert_return(bus->state == BUS_UNSET, -EPERM);
289 assert_return(!bus_pid_changed(bus), -ECHILD);
291 SET_FLAG(bus->hello_flags, KDBUS_HELLO_ACCEPT_FD, b);
295 _public_ int sd_bus_negotiate_timestamp(sd_bus *bus, int b) {
297 assert_return(bus, -EINVAL);
298 assert_return(!IN_SET(bus->state, BUS_CLOSING, BUS_CLOSED), -EPERM);
299 assert_return(!bus_pid_changed(bus), -ECHILD);
301 new_flags = bus->attach_flags;
302 SET_FLAG(new_flags, KDBUS_ATTACH_TIMESTAMP, b);
304 if (bus->attach_flags == new_flags)
307 bus->attach_flags = new_flags;
312 _public_ int sd_bus_negotiate_creds(sd_bus *bus, int b, uint64_t mask) {
315 assert_return(bus, -EINVAL);
316 assert_return(mask <= _SD_BUS_CREDS_ALL, -EINVAL);
317 assert_return(!IN_SET(bus->state, BUS_CLOSING, BUS_CLOSED), -EPERM);
318 assert_return(!bus_pid_changed(bus), -ECHILD);
320 SET_FLAG(bus->creds_mask, mask, b);
322 /* The well knowns we need unconditionally, so that matches can work */
323 bus->creds_mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME;
325 /* Make sure we don't lose the timestamp flag */
326 new_flags = (bus->attach_flags & KDBUS_ATTACH_TIMESTAMP) | attach_flags_to_kdbus(bus->creds_mask);
327 if (bus->attach_flags == new_flags)
330 bus->attach_flags = new_flags;
335 _public_ int sd_bus_set_server(sd_bus *bus, int b, sd_id128_t server_id) {
336 assert_return(bus, -EINVAL);
337 assert_return(b || sd_id128_equal(server_id, SD_ID128_NULL), -EINVAL);
338 assert_return(bus->state == BUS_UNSET, -EPERM);
339 assert_return(!bus_pid_changed(bus), -ECHILD);
341 bus->is_server = !!b;
342 bus->server_id = server_id;
346 _public_ int sd_bus_set_anonymous(sd_bus *bus, int b) {
347 assert_return(bus, -EINVAL);
348 assert_return(bus->state == BUS_UNSET, -EPERM);
349 assert_return(!bus_pid_changed(bus), -ECHILD);
351 bus->anonymous_auth = !!b;
355 _public_ int sd_bus_set_trusted(sd_bus *bus, int b) {
356 assert_return(bus, -EINVAL);
357 assert_return(bus->state == BUS_UNSET, -EPERM);
358 assert_return(!bus_pid_changed(bus), -ECHILD);
364 _public_ int sd_bus_set_description(sd_bus *bus, const char *description) {
365 assert_return(bus, -EINVAL);
366 assert_return(bus->state == BUS_UNSET, -EPERM);
367 assert_return(!bus_pid_changed(bus), -ECHILD);
369 return free_and_strdup(&bus->description, description);
372 _public_ int sd_bus_set_allow_interactive_authorization(sd_bus *bus, int b) {
373 assert_return(bus, -EINVAL);
374 assert_return(!bus_pid_changed(bus), -ECHILD);
376 bus->allow_interactive_authorization = !!b;
380 _public_ int sd_bus_get_allow_interactive_authorization(sd_bus *bus) {
381 assert_return(bus, -EINVAL);
382 assert_return(!bus_pid_changed(bus), -ECHILD);
384 return bus->allow_interactive_authorization;
387 static int hello_callback(sd_bus_message *reply, void *userdata, sd_bus_error *error) {
395 assert(IN_SET(bus->state, BUS_HELLO, BUS_CLOSING));
397 r = sd_bus_message_get_errno(reply);
401 r = sd_bus_message_read(reply, "s", &s);
405 if (!service_name_is_valid(s) || s[0] != ':')
408 bus->unique_name = strdup(s);
409 if (!bus->unique_name)
412 if (bus->state == BUS_HELLO)
413 bus->state = BUS_RUNNING;
418 static int bus_send_hello(sd_bus *bus) {
419 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
424 if (!bus->bus_client)
427 r = sd_bus_message_new_method_call(
430 "org.freedesktop.DBus",
431 "/org/freedesktop/DBus",
432 "org.freedesktop.DBus",
437 return sd_bus_call_async(bus, NULL, m, hello_callback, NULL, 0);
440 int bus_start_running(sd_bus *bus) {
443 if (bus->bus_client) {
444 bus->state = BUS_HELLO;
448 bus->state = BUS_RUNNING;
452 static int parse_address_key(const char **p, const char *key, char **value) {
453 size_t l, n = 0, allocated = 0;
463 if (strncmp(*p, key, l) != 0)
476 while (!IN_SET(*a, ';', ',', 0)) {
494 c = (char) ((x << 4) | y);
501 if (!GREEDY_REALLOC(r, allocated, n + 2))
525 static void skip_address_key(const char **p) {
529 *p += strcspn(*p, ",");
535 static int parse_unix_address(sd_bus *b, const char **p, char **guid) {
536 _cleanup_free_ char *path = NULL, *abstract = NULL;
545 while (!IN_SET(**p, 0, ';')) {
546 r = parse_address_key(p, "guid", guid);
552 r = parse_address_key(p, "path", &path);
558 r = parse_address_key(p, "abstract", &abstract);
567 if (!path && !abstract)
570 if (path && abstract)
575 if (l > sizeof(b->sockaddr.un.sun_path))
578 b->sockaddr.un.sun_family = AF_UNIX;
579 strncpy(b->sockaddr.un.sun_path, path, sizeof(b->sockaddr.un.sun_path));
580 b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + l;
581 } else if (abstract) {
582 l = strlen(abstract);
583 if (l > sizeof(b->sockaddr.un.sun_path) - 1)
586 b->sockaddr.un.sun_family = AF_UNIX;
587 b->sockaddr.un.sun_path[0] = 0;
588 strncpy(b->sockaddr.un.sun_path+1, abstract, sizeof(b->sockaddr.un.sun_path)-1);
589 b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + 1 + l;
597 static int parse_tcp_address(sd_bus *b, const char **p, char **guid) {
598 _cleanup_free_ char *host = NULL, *port = NULL, *family = NULL;
600 struct addrinfo *result, hints = {
601 .ai_socktype = SOCK_STREAM,
602 .ai_flags = AI_ADDRCONFIG,
610 while (!IN_SET(**p, 0, ';')) {
611 r = parse_address_key(p, "guid", guid);
617 r = parse_address_key(p, "host", &host);
623 r = parse_address_key(p, "port", &port);
629 r = parse_address_key(p, "family", &family);
642 if (streq(family, "ipv4"))
643 hints.ai_family = AF_INET;
644 else if (streq(family, "ipv6"))
645 hints.ai_family = AF_INET6;
650 r = getaddrinfo(host, port, &hints, &result);
654 return -EADDRNOTAVAIL;
656 memcpy(&b->sockaddr, result->ai_addr, result->ai_addrlen);
657 b->sockaddr_size = result->ai_addrlen;
659 freeaddrinfo(result);
666 static int parse_exec_address(sd_bus *b, const char **p, char **guid) {
668 unsigned n_argv = 0, j;
670 size_t allocated = 0;
678 while (!IN_SET(**p, 0, ';')) {
679 r = parse_address_key(p, "guid", guid);
685 r = parse_address_key(p, "path", &path);
691 if (startswith(*p, "argv")) {
695 ul = strtoul(*p + 4, (char**) p, 10);
696 if (errno > 0 || **p != '=' || ul > 256) {
704 if (!GREEDY_REALLOC0(argv, allocated, ul + 2)) {
712 r = parse_address_key(p, NULL, argv + ul);
727 /* Make sure there are no holes in the array, with the
728 * exception of argv[0] */
729 for (j = 1; j < n_argv; j++)
735 if (argv && argv[0] == NULL) {
736 argv[0] = strdup(path);
751 for (j = 0; j < n_argv; j++)
759 static int parse_container_unix_address(sd_bus *b, const char **p, char **guid) {
760 _cleanup_free_ char *machine = NULL, *pid = NULL;
768 while (!IN_SET(**p, 0, ';')) {
769 r = parse_address_key(p, "guid", guid);
775 r = parse_address_key(p, "machine", &machine);
781 r = parse_address_key(p, "pid", &pid);
790 if (!machine == !pid)
794 if (!machine_name_is_valid(machine))
797 free_and_replace(b->machine, machine);
799 b->machine = mfree(b->machine);
803 r = parse_pid(pid, &b->nspid);
809 b->sockaddr.un.sun_family = AF_UNIX;
810 strncpy(b->sockaddr.un.sun_path, "/var/run/dbus/system_bus_socket", sizeof(b->sockaddr.un.sun_path));
811 b->sockaddr_size = SOCKADDR_UN_LEN(b->sockaddr.un);
817 static void bus_reset_parsed_address(sd_bus *b) {
821 b->sockaddr_size = 0;
822 b->exec_argv = strv_free(b->exec_argv);
823 b->exec_path = mfree(b->exec_path);
824 b->server_id = SD_ID128_NULL;
825 b->machine = mfree(b->machine);
829 static int bus_parse_next_address(sd_bus *b) {
830 _cleanup_free_ char *guid = NULL;
838 if (b->address[b->address_index] == 0)
841 bus_reset_parsed_address(b);
843 a = b->address + b->address_index;
852 if (startswith(a, "unix:")) {
855 r = parse_unix_address(b, &a, &guid);
860 } else if (startswith(a, "tcp:")) {
863 r = parse_tcp_address(b, &a, &guid);
869 } else if (startswith(a, "unixexec:")) {
872 r = parse_exec_address(b, &a, &guid);
878 } else if (startswith(a, "x-machine-unix:")) {
881 r = parse_container_unix_address(b, &a, &guid);
894 r = sd_id128_from_string(guid, &b->server_id);
899 b->address_index = a - b->address;
903 static int bus_start_address(sd_bus *b) {
911 /* If you provide multiple different bus-addresses, we
912 * try all of them in order and use the first one that
916 r = bus_socket_exec(b);
918 else if ((b->nspid > 0 || b->machine) && b->sockaddr.sa.sa_family != AF_UNSPEC)
919 r = bus_container_connect_socket(b);
921 else if (b->sockaddr.sa.sa_family != AF_UNSPEC)
922 r = bus_socket_connect(b);
928 r = attach_io_events(b);
933 b->last_connect_error = -r;
936 r = bus_parse_next_address(b);
940 return b->last_connect_error > 0 ? -b->last_connect_error : -ECONNREFUSED;
944 int bus_next_address(sd_bus *b) {
947 bus_reset_parsed_address(b);
948 return bus_start_address(b);
951 static int bus_start_fd(sd_bus *b) {
956 assert(b->input_fd >= 0);
957 assert(b->output_fd >= 0);
959 r = fd_nonblock(b->input_fd, true);
963 r = fd_cloexec(b->input_fd, true);
967 if (b->input_fd != b->output_fd) {
968 r = fd_nonblock(b->output_fd, true);
972 r = fd_cloexec(b->output_fd, true);
977 if (fstat(b->input_fd, &st) < 0)
980 return bus_socket_take_fd(b);
983 _public_ int sd_bus_start(sd_bus *bus) {
986 assert_return(bus, -EINVAL);
987 assert_return(bus->state == BUS_UNSET, -EPERM);
988 assert_return(!bus_pid_changed(bus), -ECHILD);
990 bus->state = BUS_OPENING;
992 if (bus->is_server && bus->bus_client)
995 if (bus->input_fd >= 0)
996 r = bus_start_fd(bus);
997 else if (bus->address || bus->sockaddr.sa.sa_family != AF_UNSPEC || bus->exec_path || bus->machine)
998 r = bus_start_address(bus);
1007 return bus_send_hello(bus);
1010 _public_ int sd_bus_open(sd_bus **ret) {
1015 assert_return(ret, -EINVAL);
1017 /* Let's connect to the starter bus if it is set, and
1018 * otherwise to the bus that is appropropriate for the scope
1019 * we are running in */
1021 e = secure_getenv("DBUS_STARTER_BUS_TYPE");
1023 if (streq(e, "system"))
1024 return sd_bus_open_system(ret);
1025 #if 0 /// elogind does not support systemd user instances
1026 else if (STR_IN_SET(e, "session", "user"))
1027 return sd_bus_open_user(ret);
1031 e = secure_getenv("DBUS_STARTER_ADDRESS");
1033 #if 0 /// elogind does not support systemd user instances
1034 if (cg_pid_get_owner_uid(0, NULL) >= 0)
1035 return sd_bus_open_user(ret);
1038 return sd_bus_open_system(ret);
1045 r = sd_bus_set_address(b, e);
1049 b->bus_client = true;
1051 /* We don't know whether the bus is trusted or not, so better
1052 * be safe, and authenticate everything */
1054 b->is_local = false;
1055 b->attach_flags |= KDBUS_ATTACH_CAPS | KDBUS_ATTACH_CREDS;
1056 b->creds_mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_EFFECTIVE_CAPS;
1058 r = sd_bus_start(b);
1070 int bus_set_address_system(sd_bus *b) {
1074 e = secure_getenv("DBUS_SYSTEM_BUS_ADDRESS");
1076 return sd_bus_set_address(b, e);
1078 return sd_bus_set_address(b, DEFAULT_SYSTEM_BUS_ADDRESS);
1081 _public_ int sd_bus_open_system(sd_bus **ret) {
1085 assert_return(ret, -EINVAL);
1091 r = bus_set_address_system(b);
1095 b->bus_client = true;
1096 b->is_system = true;
1098 /* Let's do per-method access control on the system bus. We
1099 * need the caller's UID and capability set for that. */
1101 b->attach_flags |= KDBUS_ATTACH_CAPS | KDBUS_ATTACH_CREDS;
1102 b->creds_mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_EFFECTIVE_CAPS;
1105 r = sd_bus_start(b);
1117 #if 0 /// elogind can not open/use a user bus
1118 int bus_set_address_user(sd_bus *b) {
1120 _cleanup_free_ char *ee = NULL, *s = NULL;
1124 e = secure_getenv("DBUS_SESSION_BUS_ADDRESS");
1126 return sd_bus_set_address(b, e);
1128 e = secure_getenv("XDG_RUNTIME_DIR");
1132 ee = bus_address_escape(e);
1136 if (asprintf(&s, UNIX_USER_BUS_ADDRESS_FMT, ee) < 0)
1146 _public_ int sd_bus_open_user(sd_bus **ret) {
1147 #if 0 /// elogind does not support user buses
1151 assert_return(ret, -EINVAL);
1157 r = bus_set_address_user(b);
1161 b->bus_client = true;
1164 /* We don't do any per-method access control on the user
1169 r = sd_bus_start(b);
1180 return sd_bus_open_system(ret);
1184 int bus_set_address_system_remote(sd_bus *b, const char *host) {
1185 _cleanup_free_ char *e = NULL;
1186 char *m = NULL, *c = NULL;
1191 /* Let's see if we shall enter some container */
1192 m = strchr(host, ':');
1196 /* Let's make sure this is not a port of some kind,
1197 * and is a valid machine name. */
1198 if (!in_charset(m, "0123456789") && machine_name_is_valid(m)) {
1201 /* Cut out the host part */
1202 t = strndupa(host, m - host - 1);
1203 e = bus_address_escape(t);
1207 c = strjoina(",argv5=--machine=", m);
1212 e = bus_address_escape(host);
1217 b->address = strjoin("unixexec:path=ssh,argv1=-xT,argv2=--,argv3=", e, ",argv4=systemd-stdio-bridge", c);
1224 _public_ int sd_bus_open_system_remote(sd_bus **ret, const char *host) {
1228 assert_return(host, -EINVAL);
1229 assert_return(ret, -EINVAL);
1231 r = sd_bus_new(&bus);
1235 r = bus_set_address_system_remote(bus, host);
1239 bus->bus_client = true;
1240 bus->trusted = false;
1241 bus->is_system = true;
1242 bus->is_local = false;
1244 r = sd_bus_start(bus);
1256 int bus_set_address_system_machine(sd_bus *b, const char *machine) {
1257 _cleanup_free_ char *e = NULL;
1262 e = bus_address_escape(machine);
1266 b->address = strjoin("x-machine-unix:machine=", e);
1273 _public_ int sd_bus_open_system_machine(sd_bus **ret, const char *machine) {
1277 assert_return(machine, -EINVAL);
1278 assert_return(ret, -EINVAL);
1279 assert_return(machine_name_is_valid(machine), -EINVAL);
1281 r = sd_bus_new(&bus);
1285 r = bus_set_address_system_machine(bus, machine);
1289 bus->bus_client = true;
1290 bus->trusted = false;
1291 bus->is_system = true;
1292 bus->is_local = false;
1294 r = sd_bus_start(bus);
1306 _public_ void sd_bus_close(sd_bus *bus) {
1310 if (bus->state == BUS_CLOSED)
1312 if (bus_pid_changed(bus))
1315 bus->state = BUS_CLOSED;
1317 sd_bus_detach_event(bus);
1319 /* Drop all queued messages so that they drop references to
1320 * the bus object and the bus may be freed */
1321 bus_reset_queues(bus);
1326 _public_ sd_bus* sd_bus_flush_close_unref(sd_bus *bus) {
1334 return sd_bus_unref(bus);
1337 static void bus_enter_closing(sd_bus *bus) {
1340 if (!IN_SET(bus->state, BUS_OPENING, BUS_AUTHENTICATING, BUS_HELLO, BUS_RUNNING))
1343 bus->state = BUS_CLOSING;
1346 _public_ sd_bus *sd_bus_ref(sd_bus *bus) {
1351 assert_se(REFCNT_INC(bus->n_ref) >= 2);
1356 _public_ sd_bus *sd_bus_unref(sd_bus *bus) {
1362 i = REFCNT_DEC(bus->n_ref);
1370 _public_ int sd_bus_is_open(sd_bus *bus) {
1372 assert_return(bus, -EINVAL);
1373 assert_return(!bus_pid_changed(bus), -ECHILD);
1375 return BUS_IS_OPEN(bus->state);
1378 _public_ int sd_bus_can_send(sd_bus *bus, char type) {
1381 assert_return(bus, -EINVAL);
1382 assert_return(bus->state != BUS_UNSET, -ENOTCONN);
1383 assert_return(!bus_pid_changed(bus), -ECHILD);
1385 if (bus->hello_flags & KDBUS_HELLO_MONITOR)
1388 if (type == SD_BUS_TYPE_UNIX_FD) {
1389 if (!(bus->hello_flags & KDBUS_HELLO_ACCEPT_FD))
1392 r = bus_ensure_running(bus);
1396 return bus->can_fds;
1399 return bus_type_is_valid(type);
1402 _public_ int sd_bus_get_bus_id(sd_bus *bus, sd_id128_t *id) {
1405 assert_return(bus, -EINVAL);
1406 assert_return(id, -EINVAL);
1407 assert_return(!bus_pid_changed(bus), -ECHILD);
1409 r = bus_ensure_running(bus);
1413 *id = bus->server_id;
1417 static int bus_seal_message(sd_bus *b, sd_bus_message *m, usec_t timeout) {
1422 /* If we copy the same message to multiple
1423 * destinations, avoid using the same cookie
1425 b->cookie = MAX(b->cookie, BUS_MESSAGE_COOKIE(m));
1430 timeout = BUS_DEFAULT_TIMEOUT;
1432 return sd_bus_message_seal(m, ++b->cookie, timeout);
1435 static int bus_remarshal_message(sd_bus *b, sd_bus_message **m) {
1436 bool remarshal = false;
1440 /* wrong packet version */
1441 if (b->message_version != 0 && b->message_version != (*m)->header->version)
1444 /* wrong packet endianness */
1445 if (b->message_endian != 0 && b->message_endian != (*m)->header->endian)
1448 return remarshal ? bus_message_remarshal(b, m) : 0;
1451 int bus_seal_synthetic_message(sd_bus *b, sd_bus_message *m) {
1455 /* Fake some timestamps, if they were requested, and not
1456 * already initialized */
1457 if (b->attach_flags & KDBUS_ATTACH_TIMESTAMP) {
1458 if (m->realtime <= 0)
1459 m->realtime = now(CLOCK_REALTIME);
1461 if (m->monotonic <= 0)
1462 m->monotonic = now(CLOCK_MONOTONIC);
1465 /* The bus specification says the serial number cannot be 0,
1466 * hence let's fill something in for synthetic messages. Since
1467 * synthetic messages might have a fake sender and we don't
1468 * want to interfere with the real sender's serial numbers we
1469 * pick a fixed, artificial one. We use (uint32_t) -1 rather
1470 * than (uint64_t) -1 since dbus1 only had 32bit identifiers,
1471 * even though kdbus can do 64bit. */
1472 return sd_bus_message_seal(m, 0xFFFFFFFFULL, 0);
1475 static int bus_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call, size_t *idx) {
1481 r = bus_socket_write_message(bus, m, idx);
1485 if (*idx >= BUS_MESSAGE_SIZE(m))
1486 log_debug("Sent message type=%s sender=%s destination=%s path=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " signature=%s error-name=%s error-message=%s",
1487 bus_message_type_to_string(m->header->type),
1488 strna(sd_bus_message_get_sender(m)),
1489 strna(sd_bus_message_get_destination(m)),
1490 strna(sd_bus_message_get_path(m)),
1491 strna(sd_bus_message_get_interface(m)),
1492 strna(sd_bus_message_get_member(m)),
1493 BUS_MESSAGE_COOKIE(m),
1495 strna(m->root_container.signature),
1496 strna(m->error.name),
1497 strna(m->error.message));
1502 static int dispatch_wqueue(sd_bus *bus) {
1506 assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO));
1508 while (bus->wqueue_size > 0) {
1510 r = bus_write_message(bus, bus->wqueue[0], false, &bus->windex);
1514 /* Didn't do anything this time */
1516 else if (bus->windex >= BUS_MESSAGE_SIZE(bus->wqueue[0])) {
1517 /* Fully written. Let's drop the entry from
1520 * This isn't particularly optimized, but
1521 * well, this is supposed to be our worst-case
1522 * buffer only, and the socket buffer is
1523 * supposed to be our primary buffer, and if
1524 * it got full, then all bets are off
1528 sd_bus_message_unref(bus->wqueue[0]);
1529 memmove(bus->wqueue, bus->wqueue + 1, sizeof(sd_bus_message*) * bus->wqueue_size);
1539 static int bus_read_message(sd_bus *bus, bool hint_priority, int64_t priority) {
1542 return bus_socket_read_message(bus);
1545 int bus_rqueue_make_room(sd_bus *bus) {
1548 if (bus->rqueue_size >= BUS_RQUEUE_MAX)
1551 if (!GREEDY_REALLOC(bus->rqueue, bus->rqueue_allocated, bus->rqueue_size + 1))
1557 static int dispatch_rqueue(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **m) {
1562 assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO));
1564 /* Note that the priority logic is only available on kdbus,
1565 * where the rqueue is unused. We check the rqueue here
1566 * anyway, because it's simple... */
1569 if (bus->rqueue_size > 0) {
1570 /* Dispatch a queued message */
1572 *m = bus->rqueue[0];
1574 memmove(bus->rqueue, bus->rqueue + 1, sizeof(sd_bus_message*) * bus->rqueue_size);
1578 /* Try to read a new message */
1579 r = bus_read_message(bus, hint_priority, priority);
1589 static int bus_send_internal(sd_bus *bus, sd_bus_message *_m, uint64_t *cookie, bool hint_sync_call) {
1590 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = sd_bus_message_ref(_m);
1593 assert_return(m, -EINVAL);
1598 assert_return(!bus_pid_changed(bus), -ECHILD);
1600 if (!BUS_IS_OPEN(bus->state))
1604 r = sd_bus_can_send(bus, SD_BUS_TYPE_UNIX_FD);
1611 /* If the cookie number isn't kept, then we know that no reply
1613 if (!cookie && !m->sealed)
1614 m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
1616 r = bus_seal_message(bus, m, 0);
1620 /* Remarshall if we have to. This will possibly unref the
1621 * message and place a replacement in m */
1622 r = bus_remarshal_message(bus, &m);
1626 /* If this is a reply and no reply was requested, then let's
1627 * suppress this, if we can */
1631 if (IN_SET(bus->state, BUS_RUNNING, BUS_HELLO) && bus->wqueue_size <= 0) {
1634 r = bus_write_message(bus, m, hint_sync_call, &idx);
1636 if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
1637 bus_enter_closing(bus);
1644 if (idx < BUS_MESSAGE_SIZE(m)) {
1645 /* Wasn't fully written. So let's remember how
1646 * much was written. Note that the first entry
1647 * of the wqueue array is always allocated so
1648 * that we always can remember how much was
1650 bus->wqueue[0] = sd_bus_message_ref(m);
1651 bus->wqueue_size = 1;
1656 /* Just append it to the queue. */
1658 if (bus->wqueue_size >= BUS_WQUEUE_MAX)
1661 if (!GREEDY_REALLOC(bus->wqueue, bus->wqueue_allocated, bus->wqueue_size + 1))
1664 bus->wqueue[bus->wqueue_size++] = sd_bus_message_ref(m);
1669 *cookie = BUS_MESSAGE_COOKIE(m);
1674 _public_ int sd_bus_send(sd_bus *bus, sd_bus_message *m, uint64_t *cookie) {
1675 return bus_send_internal(bus, m, cookie, false);
1678 _public_ int sd_bus_send_to(sd_bus *bus, sd_bus_message *m, const char *destination, uint64_t *cookie) {
1681 assert_return(m, -EINVAL);
1686 assert_return(!bus_pid_changed(bus), -ECHILD);
1688 if (!BUS_IS_OPEN(bus->state))
1691 if (!streq_ptr(m->destination, destination)) {
1696 r = sd_bus_message_set_destination(m, destination);
1701 return sd_bus_send(bus, m, cookie);
1704 static usec_t calc_elapse(uint64_t usec) {
1705 if (usec == (uint64_t) -1)
1708 return now(CLOCK_MONOTONIC) + usec;
1711 static int timeout_compare(const void *a, const void *b) {
1712 const struct reply_callback *x = a, *y = b;
1714 if (x->timeout != 0 && y->timeout == 0)
1717 if (x->timeout == 0 && y->timeout != 0)
1720 if (x->timeout < y->timeout)
1723 if (x->timeout > y->timeout)
1729 _public_ int sd_bus_call_async(
1733 sd_bus_message_handler_t callback,
1737 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = sd_bus_message_ref(_m);
1738 _cleanup_(sd_bus_slot_unrefp) sd_bus_slot *s = NULL;
1741 assert_return(m, -EINVAL);
1742 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
1743 assert_return(!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED), -EINVAL);
1744 assert_return(callback, -EINVAL);
1749 assert_return(!bus_pid_changed(bus), -ECHILD);
1751 if (!BUS_IS_OPEN(bus->state))
1754 r = ordered_hashmap_ensure_allocated(&bus->reply_callbacks, &uint64_hash_ops);
1758 r = prioq_ensure_allocated(&bus->reply_callbacks_prioq, timeout_compare);
1762 r = bus_seal_message(bus, m, usec);
1766 r = bus_remarshal_message(bus, &m);
1770 s = bus_slot_allocate(bus, !slot, BUS_REPLY_CALLBACK, sizeof(struct reply_callback), userdata);
1774 s->reply_callback.callback = callback;
1776 s->reply_callback.cookie = BUS_MESSAGE_COOKIE(m);
1777 r = ordered_hashmap_put(bus->reply_callbacks, &s->reply_callback.cookie, &s->reply_callback);
1779 s->reply_callback.cookie = 0;
1783 s->reply_callback.timeout = calc_elapse(m->timeout);
1784 if (s->reply_callback.timeout != 0) {
1785 r = prioq_put(bus->reply_callbacks_prioq, &s->reply_callback, &s->reply_callback.prioq_idx);
1787 s->reply_callback.timeout = 0;
1792 r = sd_bus_send(bus, m, &s->reply_callback.cookie);
1803 int bus_ensure_running(sd_bus *bus) {
1808 if (IN_SET(bus->state, BUS_UNSET, BUS_CLOSED, BUS_CLOSING))
1810 if (bus->state == BUS_RUNNING)
1814 r = sd_bus_process(bus, NULL);
1817 if (bus->state == BUS_RUNNING)
1822 r = sd_bus_wait(bus, (uint64_t) -1);
1828 _public_ int sd_bus_call(
1832 sd_bus_error *error,
1833 sd_bus_message **reply) {
1835 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = sd_bus_message_ref(_m);
1841 bus_assert_return(m, -EINVAL, error);
1842 bus_assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL, error);
1843 bus_assert_return(!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED), -EINVAL, error);
1844 bus_assert_return(!bus_error_is_dirty(error), -EINVAL, error);
1849 bus_assert_return(!bus_pid_changed(bus), -ECHILD, error);
1851 if (!BUS_IS_OPEN(bus->state)) {
1856 r = bus_ensure_running(bus);
1860 i = bus->rqueue_size;
1862 r = bus_seal_message(bus, m, usec);
1866 r = bus_remarshal_message(bus, &m);
1870 r = bus_send_internal(bus, m, &cookie, true);
1874 timeout = calc_elapse(m->timeout);
1879 while (i < bus->rqueue_size) {
1880 sd_bus_message *incoming = NULL;
1882 incoming = bus->rqueue[i];
1884 if (incoming->reply_cookie == cookie) {
1885 /* Found a match! */
1887 memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1));
1889 log_debug_bus_message(incoming);
1891 if (incoming->header->type == SD_BUS_MESSAGE_METHOD_RETURN) {
1893 if (incoming->n_fds <= 0 || (bus->hello_flags & KDBUS_HELLO_ACCEPT_FD)) {
1897 sd_bus_message_unref(incoming);
1902 r = sd_bus_error_setf(error, SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Reply message contained file descriptors which I couldn't accept. Sorry.");
1903 sd_bus_message_unref(incoming);
1906 } else if (incoming->header->type == SD_BUS_MESSAGE_METHOD_ERROR) {
1907 r = sd_bus_error_copy(error, &incoming->error);
1908 sd_bus_message_unref(incoming);
1915 } else if (BUS_MESSAGE_COOKIE(incoming) == cookie &&
1918 streq(bus->unique_name, incoming->sender)) {
1920 memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1));
1923 /* Our own message? Somebody is trying
1924 * to send its own client a message,
1925 * let's not dead-lock, let's fail
1928 sd_bus_message_unref(incoming);
1933 /* Try to read more, right-away */
1937 r = bus_read_message(bus, false, 0);
1939 if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
1940 bus_enter_closing(bus);
1952 n = now(CLOCK_MONOTONIC);
1960 left = (uint64_t) -1;
1962 r = bus_poll(bus, true, left);
1970 r = dispatch_wqueue(bus);
1972 if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
1973 bus_enter_closing(bus);
1982 return sd_bus_error_set_errno(error, r);
1985 _public_ int sd_bus_get_fd(sd_bus *bus) {
1987 assert_return(bus, -EINVAL);
1988 assert_return(bus->input_fd == bus->output_fd, -EPERM);
1989 assert_return(!bus_pid_changed(bus), -ECHILD);
1991 return bus->input_fd;
1994 _public_ int sd_bus_get_events(sd_bus *bus) {
1997 assert_return(bus, -EINVAL);
1998 assert_return(!bus_pid_changed(bus), -ECHILD);
2000 if (!BUS_IS_OPEN(bus->state) && bus->state != BUS_CLOSING)
2003 if (bus->state == BUS_OPENING)
2005 else if (bus->state == BUS_AUTHENTICATING) {
2007 if (bus_socket_auth_needs_write(bus))
2012 } else if (IN_SET(bus->state, BUS_RUNNING, BUS_HELLO)) {
2013 if (bus->rqueue_size <= 0)
2015 if (bus->wqueue_size > 0)
2022 _public_ int sd_bus_get_timeout(sd_bus *bus, uint64_t *timeout_usec) {
2023 struct reply_callback *c;
2025 assert_return(bus, -EINVAL);
2026 assert_return(timeout_usec, -EINVAL);
2027 assert_return(!bus_pid_changed(bus), -ECHILD);
2029 if (!BUS_IS_OPEN(bus->state) && bus->state != BUS_CLOSING)
2032 if (bus->track_queue) {
2037 if (bus->state == BUS_CLOSING) {
2042 if (bus->state == BUS_AUTHENTICATING) {
2043 *timeout_usec = bus->auth_timeout;
2047 if (!IN_SET(bus->state, BUS_RUNNING, BUS_HELLO)) {
2048 *timeout_usec = (uint64_t) -1;
2052 if (bus->rqueue_size > 0) {
2057 c = prioq_peek(bus->reply_callbacks_prioq);
2059 *timeout_usec = (uint64_t) -1;
2063 if (c->timeout == 0) {
2064 *timeout_usec = (uint64_t) -1;
2068 *timeout_usec = c->timeout;
2072 static int process_timeout(sd_bus *bus) {
2073 _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
2074 _cleanup_(sd_bus_message_unrefp) sd_bus_message* m = NULL;
2075 struct reply_callback *c;
2082 c = prioq_peek(bus->reply_callbacks_prioq);
2086 n = now(CLOCK_MONOTONIC);
2090 r = bus_message_new_synthetic_error(
2093 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out"),
2098 r = bus_seal_synthetic_message(bus, m);
2102 assert_se(prioq_pop(bus->reply_callbacks_prioq) == c);
2105 ordered_hashmap_remove(bus->reply_callbacks, &c->cookie);
2108 slot = container_of(c, sd_bus_slot, reply_callback);
2110 bus->iteration_counter++;
2112 bus->current_message = m;
2113 bus->current_slot = sd_bus_slot_ref(slot);
2114 bus->current_handler = c->callback;
2115 bus->current_userdata = slot->userdata;
2116 r = c->callback(m, slot->userdata, &error_buffer);
2117 bus->current_userdata = NULL;
2118 bus->current_handler = NULL;
2119 bus->current_slot = NULL;
2120 bus->current_message = NULL;
2122 if (slot->floating) {
2123 bus_slot_disconnect(slot);
2124 sd_bus_slot_unref(slot);
2127 sd_bus_slot_unref(slot);
2129 return bus_maybe_reply_error(m, r, &error_buffer);
2132 static int process_hello(sd_bus *bus, sd_bus_message *m) {
2136 if (bus->state != BUS_HELLO)
2139 /* Let's make sure the first message on the bus is the HELLO
2140 * reply. But note that we don't actually parse the message
2141 * here (we leave that to the usual handling), we just verify
2142 * we don't let any earlier msg through. */
2144 if (!IN_SET(m->header->type, SD_BUS_MESSAGE_METHOD_RETURN, SD_BUS_MESSAGE_METHOD_ERROR))
2147 if (m->reply_cookie != 1)
2153 static int process_reply(sd_bus *bus, sd_bus_message *m) {
2154 _cleanup_(sd_bus_message_unrefp) sd_bus_message *synthetic_reply = NULL;
2155 _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
2156 struct reply_callback *c;
2163 if (!IN_SET(m->header->type, SD_BUS_MESSAGE_METHOD_RETURN, SD_BUS_MESSAGE_METHOD_ERROR))
2166 if (m->destination && bus->unique_name && !streq_ptr(m->destination, bus->unique_name))
2169 c = ordered_hashmap_remove(bus->reply_callbacks, &m->reply_cookie);
2175 slot = container_of(c, sd_bus_slot, reply_callback);
2177 if (m->n_fds > 0 && !(bus->hello_flags & KDBUS_HELLO_ACCEPT_FD)) {
2179 /* If the reply contained a file descriptor which we
2180 * didn't want we pass an error instead. */
2182 r = bus_message_new_synthetic_error(
2185 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Reply message contained file descriptor"),
2190 /* Copy over original timestamp */
2191 synthetic_reply->realtime = m->realtime;
2192 synthetic_reply->monotonic = m->monotonic;
2193 synthetic_reply->seqnum = m->seqnum;
2195 r = bus_seal_synthetic_message(bus, synthetic_reply);
2199 m = synthetic_reply;
2201 r = sd_bus_message_rewind(m, true);
2206 if (c->timeout != 0) {
2207 prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
2211 bus->current_slot = sd_bus_slot_ref(slot);
2212 bus->current_handler = c->callback;
2213 bus->current_userdata = slot->userdata;
2214 r = c->callback(m, slot->userdata, &error_buffer);
2215 bus->current_userdata = NULL;
2216 bus->current_handler = NULL;
2217 bus->current_slot = NULL;
2219 if (slot->floating) {
2220 bus_slot_disconnect(slot);
2221 sd_bus_slot_unref(slot);
2224 sd_bus_slot_unref(slot);
2226 return bus_maybe_reply_error(m, r, &error_buffer);
2229 static int process_filter(sd_bus *bus, sd_bus_message *m) {
2230 _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
2231 struct filter_callback *l;
2238 bus->filter_callbacks_modified = false;
2240 LIST_FOREACH(callbacks, l, bus->filter_callbacks) {
2243 if (bus->filter_callbacks_modified)
2246 /* Don't run this more than once per iteration */
2247 if (l->last_iteration == bus->iteration_counter)
2250 l->last_iteration = bus->iteration_counter;
2252 r = sd_bus_message_rewind(m, true);
2256 slot = container_of(l, sd_bus_slot, filter_callback);
2258 bus->current_slot = sd_bus_slot_ref(slot);
2259 bus->current_handler = l->callback;
2260 bus->current_userdata = slot->userdata;
2261 r = l->callback(m, slot->userdata, &error_buffer);
2262 bus->current_userdata = NULL;
2263 bus->current_handler = NULL;
2264 bus->current_slot = sd_bus_slot_unref(slot);
2266 r = bus_maybe_reply_error(m, r, &error_buffer);
2272 } while (bus->filter_callbacks_modified);
2277 static int process_match(sd_bus *bus, sd_bus_message *m) {
2284 bus->match_callbacks_modified = false;
2286 r = bus_match_run(bus, &bus->match_callbacks, m);
2290 } while (bus->match_callbacks_modified);
2295 static int process_builtin(sd_bus *bus, sd_bus_message *m) {
2296 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
2302 if (bus->hello_flags & KDBUS_HELLO_MONITOR)
2305 if (bus->manual_peer_interface)
2308 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
2311 if (!streq_ptr(m->interface, "org.freedesktop.DBus.Peer"))
2314 if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
2317 if (streq_ptr(m->member, "Ping"))
2318 r = sd_bus_message_new_method_return(m, &reply);
2319 else if (streq_ptr(m->member, "GetMachineId")) {
2323 r = sd_id128_get_machine(&id);
2327 r = sd_bus_message_new_method_return(m, &reply);
2331 r = sd_bus_message_append(reply, "s", sd_id128_to_string(id, sid));
2333 r = sd_bus_message_new_method_errorf(
2335 SD_BUS_ERROR_UNKNOWN_METHOD,
2336 "Unknown method '%s' on interface '%s'.", m->member, m->interface);
2342 r = sd_bus_send(bus, reply, NULL);
2349 static int process_fd_check(sd_bus *bus, sd_bus_message *m) {
2353 /* If we got a message with a file descriptor which we didn't
2354 * want to accept, then let's drop it. How can this even
2355 * happen? For example, when the kernel queues a message into
2356 * an activatable names's queue which allows fds, and then is
2357 * delivered to us later even though we ourselves did not
2360 if (bus->hello_flags & KDBUS_HELLO_MONITOR)
2366 if (bus->hello_flags & KDBUS_HELLO_ACCEPT_FD)
2369 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
2370 return 1; /* just eat it up */
2372 return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Message contains file descriptors, which I cannot accept. Sorry.");
2375 static int process_message(sd_bus *bus, sd_bus_message *m) {
2381 bus->current_message = m;
2382 bus->iteration_counter++;
2384 log_debug_bus_message(m);
2386 r = process_hello(bus, m);
2390 r = process_reply(bus, m);
2394 r = process_fd_check(bus, m);
2398 r = process_filter(bus, m);
2402 r = process_match(bus, m);
2406 r = process_builtin(bus, m);
2410 r = bus_process_object(bus, m);
2413 bus->current_message = NULL;
2417 static int dispatch_track(sd_bus *bus) {
2420 if (!bus->track_queue)
2423 bus_track_dispatch(bus->track_queue);
2427 static int process_running(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **ret) {
2428 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
2432 assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO));
2434 r = process_timeout(bus);
2438 r = dispatch_wqueue(bus);
2442 r = dispatch_track(bus);
2446 r = dispatch_rqueue(bus, hint_priority, priority, &m);
2452 r = process_message(bus, m);
2457 r = sd_bus_message_rewind(m, true);
2466 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL) {
2468 log_debug("Unprocessed message call sender=%s object=%s interface=%s member=%s",
2469 strna(sd_bus_message_get_sender(m)),
2470 strna(sd_bus_message_get_path(m)),
2471 strna(sd_bus_message_get_interface(m)),
2472 strna(sd_bus_message_get_member(m)));
2474 r = sd_bus_reply_method_errorf(
2476 SD_BUS_ERROR_UNKNOWN_OBJECT,
2477 "Unknown object '%s'.", m->path);
2491 static int bus_exit_now(sd_bus *bus) {
2494 /* Exit due to close, if this is requested. If this is bus object is attached to an event source, invokes
2495 * sd_event_exit(), otherwise invokes libc exit(). */
2497 if (bus->exited) /* did we already exit? */
2499 if (!bus->exit_triggered) /* was the exit condition triggered? */
2501 if (!bus->exit_on_disconnect) /* Shall we actually exit on disconnection? */
2504 bus->exited = true; /* never exit more than once */
2506 log_debug("Bus connection disconnected, exiting.");
2509 return sd_event_exit(bus->event, EXIT_FAILURE);
2513 assert_not_reached("exit() didn't exit?");
2516 static int process_closing_reply_callback(sd_bus *bus, struct reply_callback *c) {
2517 _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
2518 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
2525 r = bus_message_new_synthetic_error(
2528 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Connection terminated"),
2533 r = bus_seal_synthetic_message(bus, m);
2537 if (c->timeout != 0) {
2538 prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
2542 ordered_hashmap_remove(bus->reply_callbacks, &c->cookie);
2545 slot = container_of(c, sd_bus_slot, reply_callback);
2547 bus->iteration_counter++;
2549 bus->current_message = m;
2550 bus->current_slot = sd_bus_slot_ref(slot);
2551 bus->current_handler = c->callback;
2552 bus->current_userdata = slot->userdata;
2553 r = c->callback(m, slot->userdata, &error_buffer);
2554 bus->current_userdata = NULL;
2555 bus->current_handler = NULL;
2556 bus->current_slot = NULL;
2557 bus->current_message = NULL;
2559 if (slot->floating) {
2560 bus_slot_disconnect(slot);
2561 sd_bus_slot_unref(slot);
2564 sd_bus_slot_unref(slot);
2566 return bus_maybe_reply_error(m, r, &error_buffer);
2569 static int process_closing(sd_bus *bus, sd_bus_message **ret) {
2570 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
2571 struct reply_callback *c;
2575 assert(bus->state == BUS_CLOSING);
2577 /* First, fail all outstanding method calls */
2578 c = ordered_hashmap_first(bus->reply_callbacks);
2580 return process_closing_reply_callback(bus, c);
2582 /* Then, fake-drop all remaining bus tracking references */
2584 bus_track_close(bus->tracks);
2588 /* Then, synthesize a Disconnected message */
2589 r = sd_bus_message_new_signal(
2592 "/org/freedesktop/DBus/Local",
2593 "org.freedesktop.DBus.Local",
2598 bus_message_set_sender_local(bus, m);
2600 r = bus_seal_synthetic_message(bus, m);
2606 bus->current_message = m;
2607 bus->iteration_counter++;
2609 r = process_filter(bus, m);
2613 r = process_match(bus, m);
2617 /* Nothing else to do, exit now, if the condition holds */
2618 bus->exit_triggered = true;
2619 (void) bus_exit_now(bus);
2629 bus->current_message = NULL;
2634 static int bus_process_internal(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **ret) {
2635 BUS_DONT_DESTROY(bus);
2638 /* Returns 0 when we didn't do anything. This should cause the
2639 * caller to invoke sd_bus_wait() before returning the next
2640 * time. Returns > 0 when we did something, which possibly
2641 * means *ret is filled in with an unprocessed message. */
2643 assert_return(bus, -EINVAL);
2644 assert_return(!bus_pid_changed(bus), -ECHILD);
2646 /* We don't allow recursively invoking sd_bus_process(). */
2647 assert_return(!bus->current_message, -EBUSY);
2648 assert(!bus->current_slot);
2650 switch (bus->state) {
2659 r = bus_socket_process_opening(bus);
2660 if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
2661 bus_enter_closing(bus);
2669 case BUS_AUTHENTICATING:
2670 r = bus_socket_process_authenticating(bus);
2671 if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
2672 bus_enter_closing(bus);
2684 r = process_running(bus, hint_priority, priority, ret);
2685 if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
2686 bus_enter_closing(bus);
2696 return process_closing(bus, ret);
2699 assert_not_reached("Unknown state");
2702 _public_ int sd_bus_process(sd_bus *bus, sd_bus_message **ret) {
2703 return bus_process_internal(bus, false, 0, ret);
2706 _public_ int sd_bus_process_priority(sd_bus *bus, int64_t priority, sd_bus_message **ret) {
2707 return bus_process_internal(bus, true, priority, ret);
2710 static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec) {
2711 struct pollfd p[2] = {};
2714 usec_t m = USEC_INFINITY;
2718 if (bus->state == BUS_CLOSING)
2721 if (!BUS_IS_OPEN(bus->state))
2724 e = sd_bus_get_events(bus);
2729 /* The caller really needs some more data, he doesn't
2730 * care about what's already read, or any timeouts
2731 * except its own. */
2735 /* The caller wants to process if there's something to
2736 * process, but doesn't care otherwise */
2738 r = sd_bus_get_timeout(bus, &until);
2743 nw = now(CLOCK_MONOTONIC);
2744 m = until > nw ? until - nw : 0;
2748 if (timeout_usec != (uint64_t) -1 && (m == (uint64_t) -1 || timeout_usec < m))
2751 p[0].fd = bus->input_fd;
2752 if (bus->output_fd == bus->input_fd) {
2756 p[0].events = e & POLLIN;
2757 p[1].fd = bus->output_fd;
2758 p[1].events = e & POLLOUT;
2762 r = ppoll(p, n, m == (uint64_t) -1 ? NULL : timespec_store(&ts, m), NULL);
2766 return r > 0 ? 1 : 0;
2769 _public_ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) {
2771 assert_return(bus, -EINVAL);
2772 assert_return(!bus_pid_changed(bus), -ECHILD);
2774 if (bus->state == BUS_CLOSING)
2777 if (!BUS_IS_OPEN(bus->state))
2780 if (bus->rqueue_size > 0)
2783 return bus_poll(bus, false, timeout_usec);
2786 _public_ int sd_bus_flush(sd_bus *bus) {
2789 assert_return(bus, -EINVAL);
2790 assert_return(!bus_pid_changed(bus), -ECHILD);
2792 if (bus->state == BUS_CLOSING)
2795 if (!BUS_IS_OPEN(bus->state))
2798 r = bus_ensure_running(bus);
2802 if (bus->wqueue_size <= 0)
2806 r = dispatch_wqueue(bus);
2808 if (IN_SET(r, -ENOTCONN, -ECONNRESET, -EPIPE, -ESHUTDOWN)) {
2809 bus_enter_closing(bus);
2816 if (bus->wqueue_size <= 0)
2819 r = bus_poll(bus, false, (uint64_t) -1);
2825 _public_ int sd_bus_add_filter(
2828 sd_bus_message_handler_t callback,
2833 assert_return(bus, -EINVAL);
2834 assert_return(callback, -EINVAL);
2835 assert_return(!bus_pid_changed(bus), -ECHILD);
2837 s = bus_slot_allocate(bus, !slot, BUS_FILTER_CALLBACK, sizeof(struct filter_callback), userdata);
2841 s->filter_callback.callback = callback;
2843 bus->filter_callbacks_modified = true;
2844 LIST_PREPEND(callbacks, bus->filter_callbacks, &s->filter_callback);
2852 _public_ int sd_bus_add_match(
2856 sd_bus_message_handler_t callback,
2859 struct bus_match_component *components = NULL;
2860 unsigned n_components = 0;
2861 sd_bus_slot *s = NULL;
2864 assert_return(bus, -EINVAL);
2865 assert_return(match, -EINVAL);
2866 assert_return(!bus_pid_changed(bus), -ECHILD);
2868 r = bus_match_parse(match, &components, &n_components);
2872 s = bus_slot_allocate(bus, !slot, BUS_MATCH_CALLBACK, sizeof(struct match_callback), userdata);
2878 s->match_callback.callback = callback;
2880 if (bus->bus_client) {
2881 enum bus_match_scope scope;
2883 scope = bus_match_get_scope(components, n_components);
2885 /* Do not install server-side matches for matches
2886 * against the local service, interface or bus path. */
2887 if (scope != BUS_MATCH_LOCAL) {
2889 /* We store the original match string, so that
2890 * we can use it to remove the match again. */
2892 s->match_callback.match_string = strdup(match);
2893 if (!s->match_callback.match_string) {
2898 r = bus_add_match_internal(bus, s->match_callback.match_string, components, n_components);
2902 s->match_added = true;
2906 bus->match_callbacks_modified = true;
2907 r = bus_match_add(&bus->match_callbacks, components, n_components, &s->match_callback);
2916 bus_match_parse_free(components, n_components);
2917 sd_bus_slot_unref(s);
2922 #if 0 /// UNNEEDED by elogind
2923 int bus_remove_match_by_string(
2926 sd_bus_message_handler_t callback,
2929 struct bus_match_component *components = NULL;
2930 unsigned n_components = 0;
2931 struct match_callback *c;
2934 assert_return(bus, -EINVAL);
2935 assert_return(match, -EINVAL);
2936 assert_return(!bus_pid_changed(bus), -ECHILD);
2938 r = bus_match_parse(match, &components, &n_components);
2942 r = bus_match_find(&bus->match_callbacks, components, n_components, NULL, NULL, &c);
2946 sd_bus_slot_unref(container_of(c, sd_bus_slot, match_callback));
2949 bus_match_parse_free(components, n_components);
2955 bool bus_pid_changed(sd_bus *bus) {
2958 /* We don't support people creating a bus connection and
2959 * keeping it around over a fork(). Let's complain. */
2961 return bus->original_pid != getpid_cached();
2964 static int io_callback(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
2965 sd_bus *bus = userdata;
2970 r = sd_bus_process(bus, NULL);
2977 static int time_callback(sd_event_source *s, uint64_t usec, void *userdata) {
2978 sd_bus *bus = userdata;
2983 r = sd_bus_process(bus, NULL);
2990 static int prepare_callback(sd_event_source *s, void *userdata) {
2991 sd_bus *bus = userdata;
2998 e = sd_bus_get_events(bus);
3002 if (bus->output_fd != bus->input_fd) {
3004 r = sd_event_source_set_io_events(bus->input_io_event_source, e & POLLIN);
3008 r = sd_event_source_set_io_events(bus->output_io_event_source, e & POLLOUT);
3012 r = sd_event_source_set_io_events(bus->input_io_event_source, e);
3017 r = sd_bus_get_timeout(bus, &until);
3023 j = sd_event_source_set_time(bus->time_event_source, until);
3028 r = sd_event_source_set_enabled(bus->time_event_source, r > 0);
3035 static int quit_callback(sd_event_source *event, void *userdata) {
3036 sd_bus *bus = userdata;
3046 static int attach_io_events(sd_bus *bus) {
3051 if (bus->input_fd < 0)
3057 if (!bus->input_io_event_source) {
3058 r = sd_event_add_io(bus->event, &bus->input_io_event_source, bus->input_fd, 0, io_callback, bus);
3062 r = sd_event_source_set_prepare(bus->input_io_event_source, prepare_callback);
3066 r = sd_event_source_set_priority(bus->input_io_event_source, bus->event_priority);
3070 r = sd_event_source_set_description(bus->input_io_event_source, "bus-input");
3072 r = sd_event_source_set_io_fd(bus->input_io_event_source, bus->input_fd);
3077 if (bus->output_fd != bus->input_fd) {
3078 assert(bus->output_fd >= 0);
3080 if (!bus->output_io_event_source) {
3081 r = sd_event_add_io(bus->event, &bus->output_io_event_source, bus->output_fd, 0, io_callback, bus);
3085 r = sd_event_source_set_priority(bus->output_io_event_source, bus->event_priority);
3089 r = sd_event_source_set_description(bus->input_io_event_source, "bus-output");
3091 r = sd_event_source_set_io_fd(bus->output_io_event_source, bus->output_fd);
3100 static void detach_io_events(sd_bus *bus) {
3103 if (bus->input_io_event_source) {
3104 sd_event_source_set_enabled(bus->input_io_event_source, SD_EVENT_OFF);
3105 bus->input_io_event_source = sd_event_source_unref(bus->input_io_event_source);
3108 if (bus->output_io_event_source) {
3109 sd_event_source_set_enabled(bus->output_io_event_source, SD_EVENT_OFF);
3110 bus->output_io_event_source = sd_event_source_unref(bus->output_io_event_source);
3114 _public_ int sd_bus_attach_event(sd_bus *bus, sd_event *event, int priority) {
3117 assert_return(bus, -EINVAL);
3118 assert_return(!bus->event, -EBUSY);
3120 assert(!bus->input_io_event_source);
3121 assert(!bus->output_io_event_source);
3122 assert(!bus->time_event_source);
3125 bus->event = sd_event_ref(event);
3127 r = sd_event_default(&bus->event);
3132 bus->event_priority = priority;
3134 r = sd_event_add_time(bus->event, &bus->time_event_source, CLOCK_MONOTONIC, 0, 0, time_callback, bus);
3138 r = sd_event_source_set_priority(bus->time_event_source, priority);
3142 r = sd_event_source_set_description(bus->time_event_source, "bus-time");
3146 r = sd_event_add_exit(bus->event, &bus->quit_event_source, quit_callback, bus);
3150 r = sd_event_source_set_description(bus->quit_event_source, "bus-exit");
3154 r = attach_io_events(bus);
3161 sd_bus_detach_event(bus);
3165 _public_ int sd_bus_detach_event(sd_bus *bus) {
3166 assert_return(bus, -EINVAL);
3171 detach_io_events(bus);
3173 if (bus->time_event_source) {
3174 sd_event_source_set_enabled(bus->time_event_source, SD_EVENT_OFF);
3175 bus->time_event_source = sd_event_source_unref(bus->time_event_source);
3178 if (bus->quit_event_source) {
3179 sd_event_source_set_enabled(bus->quit_event_source, SD_EVENT_OFF);
3180 bus->quit_event_source = sd_event_source_unref(bus->quit_event_source);
3183 bus->event = sd_event_unref(bus->event);
3187 _public_ sd_event* sd_bus_get_event(sd_bus *bus) {
3188 assert_return(bus, NULL);
3193 _public_ sd_bus_message* sd_bus_get_current_message(sd_bus *bus) {
3194 assert_return(bus, NULL);
3196 return bus->current_message;
3199 _public_ sd_bus_slot* sd_bus_get_current_slot(sd_bus *bus) {
3200 assert_return(bus, NULL);
3202 return bus->current_slot;
3205 _public_ sd_bus_message_handler_t sd_bus_get_current_handler(sd_bus *bus) {
3206 assert_return(bus, NULL);
3208 return bus->current_handler;
3211 _public_ void* sd_bus_get_current_userdata(sd_bus *bus) {
3212 assert_return(bus, NULL);
3214 return bus->current_userdata;
3217 static int bus_default(int (*bus_open)(sd_bus **), sd_bus **default_bus, sd_bus **ret) {
3222 assert(default_bus);
3225 return !!*default_bus;
3228 *ret = sd_bus_ref(*default_bus);
3236 b->default_bus_ptr = default_bus;
3244 _public_ int sd_bus_default_system(sd_bus **ret) {
3245 return bus_default(sd_bus_open_system, &default_system_bus, ret);
3249 _public_ int sd_bus_default_user(sd_bus **ret) {
3250 #if 0 /// elogind does not support user buses
3251 return bus_default(sd_bus_open_user, &default_user_bus, ret);
3253 return sd_bus_default_system(ret);
3257 _public_ int sd_bus_default(sd_bus **ret) {
3261 /* Let's try our best to reuse another cached connection. If
3262 * the starter bus type is set, connect via our normal
3263 * connection logic, ignoring $DBUS_STARTER_ADDRESS, so that
3264 * we can share the connection with the user/system default
3267 e = secure_getenv("DBUS_STARTER_BUS_TYPE");
3269 if (streq(e, "system"))
3270 return sd_bus_default_system(ret);
3271 #if 0 /// elogind does not support systemd units
3272 else if (STR_IN_SET(e, "user", "session"))
3273 return sd_bus_default_user(ret);
3277 /* No type is specified, so we have not other option than to
3278 * use the starter address if it is set. */
3279 e = secure_getenv("DBUS_STARTER_ADDRESS");
3281 return bus_default(sd_bus_open, &default_starter_bus, ret);
3283 /* Finally, if nothing is set use the cached connection for
3284 * the right scope */
3286 #if 0 /// elogind does not support systemd user instances
3287 if (cg_pid_get_owner_uid(0, NULL) >= 0)
3288 return sd_bus_default_user(ret);
3291 return sd_bus_default_system(ret);
3294 _public_ int sd_bus_get_tid(sd_bus *b, pid_t *tid) {
3295 assert_return(b, -EINVAL);
3296 assert_return(tid, -EINVAL);
3297 assert_return(!bus_pid_changed(b), -ECHILD);
3305 return sd_event_get_tid(b->event, tid);
3310 _public_ int sd_bus_path_encode(const char *prefix, const char *external_id, char **ret_path) {
3311 _cleanup_free_ char *e = NULL;
3314 assert_return(object_path_is_valid(prefix), -EINVAL);
3315 assert_return(external_id, -EINVAL);
3316 assert_return(ret_path, -EINVAL);
3318 e = bus_label_escape(external_id);
3322 ret = strjoin(prefix, "/", e);
3330 _public_ int sd_bus_path_decode(const char *path, const char *prefix, char **external_id) {
3334 assert_return(object_path_is_valid(path), -EINVAL);
3335 assert_return(object_path_is_valid(prefix), -EINVAL);
3336 assert_return(external_id, -EINVAL);
3338 e = object_path_startswith(path, prefix);
3340 *external_id = NULL;
3344 ret = bus_label_unescape(e);
3352 _public_ int sd_bus_path_encode_many(char **out, const char *path_template, ...) {
3353 _cleanup_strv_free_ char **labels = NULL;
3354 char *path, *path_pos, **label_pos;
3355 const char *sep, *template_pos;
3360 assert_return(out, -EINVAL);
3361 assert_return(path_template, -EINVAL);
3363 path_length = strlen(path_template);
3365 va_start(list, path_template);
3366 for (sep = strchr(path_template, '%'); sep; sep = strchr(sep + 1, '%')) {
3370 arg = va_arg(list, const char *);
3376 label = bus_label_escape(arg);
3382 r = strv_consume(&labels, label);
3388 /* add label length, but account for the format character */
3389 path_length += strlen(label) - 1;
3393 path = malloc(path_length + 1);
3400 for (template_pos = path_template; *template_pos; ) {
3401 sep = strchrnul(template_pos, '%');
3402 path_pos = mempcpy(path_pos, template_pos, sep - template_pos);
3406 path_pos = stpcpy(path_pos, *label_pos++);
3407 template_pos = sep + 1;
3415 _public_ int sd_bus_path_decode_many(const char *path, const char *path_template, ...) {
3416 _cleanup_strv_free_ char **labels = NULL;
3417 const char *template_pos, *path_pos;
3423 * This decodes an object-path based on a template argument. The
3424 * template consists of a verbatim path, optionally including special
3427 * - Each occurrence of '%' in the template matches an arbitrary
3428 * substring of a label in the given path. At most one such
3429 * directive is allowed per label. For each such directive, the
3430 * caller must provide an output parameter (char **) via va_arg. If
3431 * NULL is passed, the given label is verified, but not returned.
3432 * For each matched label, the *decoded* label is stored in the
3433 * passed output argument, and the caller is responsible to free
3434 * it. Note that the output arguments are only modified if the
3435 * actualy path matched the template. Otherwise, they're left
3438 * This function returns <0 on error, 0 if the path does not match the
3439 * template, 1 if it matched.
3442 assert_return(path, -EINVAL);
3443 assert_return(path_template, -EINVAL);
3447 for (template_pos = path_template; *template_pos; ) {
3452 /* verify everything until the next '%' matches verbatim */
3453 sep = strchrnul(template_pos, '%');
3454 length = sep - template_pos;
3455 if (strncmp(path_pos, template_pos, length))
3459 template_pos += length;
3464 /* We found the next '%' character. Everything up until here
3465 * matched. We now skip ahead to the end of this label and make
3466 * sure it matches the tail of the label in the path. Then we
3467 * decode the string in-between and save it for later use. */
3469 ++template_pos; /* skip over '%' */
3471 sep = strchrnul(template_pos, '/');
3472 length = sep - template_pos; /* length of suffix to match verbatim */
3474 /* verify the suffixes match */
3475 sep = strchrnul(path_pos, '/');
3476 if (sep - path_pos < (ssize_t)length ||
3477 strncmp(sep - length, template_pos, length))
3480 template_pos += length; /* skip over matched label */
3481 length = sep - path_pos - length; /* length of sub-label to decode */
3483 /* store unescaped label for later use */
3484 label = bus_label_unescape_n(path_pos, length);
3488 r = strv_consume(&labels, label);
3492 path_pos = sep; /* skip decoded label and suffix */
3495 /* end of template must match end of path */
3499 /* copy the labels over to the caller */
3500 va_start(list, path_template);
3501 for (label_pos = labels; label_pos && *label_pos; ++label_pos) {
3504 arg = va_arg(list, char **);
3512 labels = mfree(labels);
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;