]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-bus/sd-bus.c
core: rework context initialization/destruction logic
[thirdparty/systemd.git] / src / libsystemd / sd-bus / sd-bus.c
CommitLineData
de1c301e
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2013 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <endian.h>
23#include <assert.h>
24#include <stdlib.h>
25#include <unistd.h>
26#include <netdb.h>
27#include <sys/poll.h>
28#include <byteswap.h>
63edf05e 29#include <sys/mman.h>
45fbe937 30#include <pthread.h>
de1c301e
LP
31
32#include "util.h"
33#include "macro.h"
2fd9ae2e 34#include "strv.h"
0a72c2bd 35#include "set.h"
6c03089c 36#include "missing.h"
ab9001a1 37#include "def.h"
af08d2f9 38#include "cgroup-util.h"
f01de965 39#include "bus-label.h"
de1c301e
LP
40
41#include "sd-bus.h"
42#include "bus-internal.h"
43#include "bus-message.h"
44#include "bus-type.h"
a7e3212d 45#include "bus-socket.h"
6629161f 46#include "bus-kernel.h"
392d5b37 47#include "bus-control.h"
29ddb38f
LP
48#include "bus-introspect.h"
49#include "bus-signature.h"
992c052c 50#include "bus-objects.h"
40ca29a1 51#include "bus-util.h"
a7893c6b 52#include "bus-container.h"
0461f8cd 53#include "bus-protocol.h"
8f8f05a9 54#include "bus-track.h"
de1c301e 55
e3017af9 56static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec);
1e05d493
LP
57static int attach_io_events(sd_bus *b);
58static void detach_io_events(sd_bus *b);
e3017af9 59
f54514f3
LP
60static void bus_close_fds(sd_bus *b) {
61 assert(b);
62
1e05d493
LP
63 detach_io_events(b);
64
f54514f3 65 if (b->input_fd >= 0)
03e334a1 66 safe_close(b->input_fd);
f54514f3
LP
67
68 if (b->output_fd >= 0 && b->output_fd != b->input_fd)
03e334a1 69 safe_close(b->output_fd);
f54514f3
LP
70
71 b->input_fd = b->output_fd = -1;
72}
73
29ddb38f
LP
74static void bus_node_destroy(sd_bus *b, struct node *n) {
75 struct node_callback *c;
76 struct node_vtable *v;
77 struct node_enumerator *e;
78
79 assert(b);
80
81 if (!n)
82 return;
83
84 while (n->child)
85 bus_node_destroy(b, n->child);
86
87 while ((c = n->callbacks)) {
71fda00f 88 LIST_REMOVE(callbacks, n->callbacks, c);
29ddb38f
LP
89 free(c);
90 }
91
92 while ((v = n->vtables)) {
71fda00f 93 LIST_REMOVE(vtables, n->vtables, v);
29ddb38f
LP
94 free(v->interface);
95 free(v);
96 }
97
98 while ((e = n->enumerators)) {
71fda00f 99 LIST_REMOVE(enumerators, n->enumerators, e);
29ddb38f
LP
100 free(e);
101 }
102
103 if (n->parent)
71fda00f 104 LIST_REMOVE(siblings, n->parent->child, n);
29ddb38f
LP
105
106 assert_se(hashmap_remove(b->nodes, n->path) == n);
107 free(n->path);
108 free(n);
109}
110
0e586eae 111static void bus_reset_queues(sd_bus *b) {
0e586eae
LP
112 assert(b);
113
f389bf15
LP
114 while (b->rqueue_size > 0)
115 sd_bus_message_unref(b->rqueue[--b->rqueue_size]);
116
0e586eae 117 free(b->rqueue);
f389bf15
LP
118 b->rqueue = NULL;
119 b->rqueue_allocated = 0;
0e586eae 120
f389bf15
LP
121 while (b->wqueue_size > 0)
122 sd_bus_message_unref(b->wqueue[--b->wqueue_size]);
0e586eae 123
f389bf15
LP
124 free(b->wqueue);
125 b->wqueue = NULL;
126 b->wqueue_allocated = 0;
0e586eae
LP
127}
128
de1c301e
LP
129static void bus_free(sd_bus *b) {
130 struct filter_callback *f;
29ddb38f 131 struct node *n;
de1c301e
LP
132
133 assert(b);
134
8f8f05a9
LP
135 assert(!b->track_queue);
136
40ca29a1
LP
137 sd_bus_detach_event(b);
138
f4d140e9
LP
139 if (b->default_bus_ptr)
140 *b->default_bus_ptr = NULL;
141
f54514f3 142 bus_close_fds(b);
de1c301e 143
63edf05e
LP
144 if (b->kdbus_buffer)
145 munmap(b->kdbus_buffer, KDBUS_POOL_SIZE);
146
de1c301e 147 free(b->rbuffer);
89ffcd2a 148 free(b->unique_name);
2181a7f5 149 free(b->auth_buffer);
89ffcd2a 150 free(b->address);
e9a967f9 151 free(b->kernel);
a7893c6b 152 free(b->machine);
8a0e0ed9 153 free(b->fake_label);
751bc6ac 154 free(b->cgroup_root);
5972fe95 155 free(b->connection_name);
89ffcd2a 156
2fd9ae2e
LP
157 free(b->exec_path);
158 strv_free(b->exec_argv);
159
2c93b4ef
LP
160 close_many(b->fds, b->n_fds);
161 free(b->fds);
162
0e586eae 163 bus_reset_queues(b);
de1c301e
LP
164
165 hashmap_free_free(b->reply_callbacks);
e3017af9 166 prioq_free(b->reply_callbacks_prioq);
de1c301e
LP
167
168 while ((f = b->filter_callbacks)) {
71fda00f 169 LIST_REMOVE(callbacks, b->filter_callbacks, f);
de1c301e
LP
170 free(f);
171 }
172
392d5b37
LP
173 bus_match_free(&b->match_callbacks);
174
29ddb38f
LP
175 hashmap_free_free(b->vtable_methods);
176 hashmap_free_free(b->vtable_properties);
177
178 while ((n = hashmap_first(b->nodes)))
179 bus_node_destroy(b, n);
180
181 hashmap_free(b->nodes);
182
bc7fd8cd
LP
183 bus_kernel_flush_memfd(b);
184
45fbe937
LP
185 assert_se(pthread_mutex_destroy(&b->memfd_cache_mutex) == 0);
186
de1c301e
LP
187 free(b);
188}
189
d9f644e2 190_public_ int sd_bus_new(sd_bus **ret) {
de1c301e
LP
191 sd_bus *r;
192
d6888822 193 assert_return(ret, -EINVAL);
021a1e78 194
de1c301e
LP
195 r = new0(sd_bus, 1);
196 if (!r)
021a1e78 197 return -ENOMEM;
de1c301e 198
e4ee6e5c 199 r->n_ref = REFCNT_INIT;
e82c9509 200 r->input_fd = r->output_fd = -1;
de1c301e 201 r->message_version = 1;
3310dfd5 202 r->creds_mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME;
d21a7bb1
DM
203 r->hello_flags |= KDBUS_HELLO_ACCEPT_FD;
204 r->attach_flags |= KDBUS_ATTACH_NAMES;
d5a2b9a6 205 r->original_pid = getpid();
de1c301e 206
45fbe937
LP
207 assert_se(pthread_mutex_init(&r->memfd_cache_mutex, NULL) == 0);
208
de1c301e
LP
209 /* We guarantee that wqueue always has space for at least one
210 * entry */
821e0756 211 if (!GREEDY_REALLOC(r->wqueue, r->wqueue_allocated, 1)) {
de1c301e 212 free(r);
021a1e78 213 return -ENOMEM;
de1c301e
LP
214 }
215
021a1e78
LP
216 *ret = r;
217 return 0;
218}
219
d9f644e2 220_public_ int sd_bus_set_address(sd_bus *bus, const char *address) {
021a1e78
LP
221 char *a;
222
d6888822
LP
223 assert_return(bus, -EINVAL);
224 assert_return(bus->state == BUS_UNSET, -EPERM);
225 assert_return(address, -EINVAL);
226 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78
LP
227
228 a = strdup(address);
229 if (!a)
230 return -ENOMEM;
231
232 free(bus->address);
233 bus->address = a;
234
235 return 0;
236}
237
d9f644e2 238_public_ int sd_bus_set_fd(sd_bus *bus, int input_fd, int output_fd) {
d6888822
LP
239 assert_return(bus, -EINVAL);
240 assert_return(bus->state == BUS_UNSET, -EPERM);
241 assert_return(input_fd >= 0, -EINVAL);
242 assert_return(output_fd >= 0, -EINVAL);
243 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78 244
e82c9509
LP
245 bus->input_fd = input_fd;
246 bus->output_fd = output_fd;
021a1e78
LP
247 return 0;
248}
249
d9f644e2 250_public_ int sd_bus_set_exec(sd_bus *bus, const char *path, char *const argv[]) {
2fd9ae2e
LP
251 char *p, **a;
252
d6888822
LP
253 assert_return(bus, -EINVAL);
254 assert_return(bus->state == BUS_UNSET, -EPERM);
255 assert_return(path, -EINVAL);
256 assert_return(!strv_isempty(argv), -EINVAL);
257 assert_return(!bus_pid_changed(bus), -ECHILD);
2fd9ae2e
LP
258
259 p = strdup(path);
260 if (!p)
261 return -ENOMEM;
262
263 a = strv_copy(argv);
264 if (!a) {
265 free(p);
266 return -ENOMEM;
267 }
268
269 free(bus->exec_path);
270 strv_free(bus->exec_argv);
271
272 bus->exec_path = p;
273 bus->exec_argv = a;
274
275 return 0;
276}
277
d9f644e2 278_public_ int sd_bus_set_bus_client(sd_bus *bus, int b) {
d6888822
LP
279 assert_return(bus, -EINVAL);
280 assert_return(bus->state == BUS_UNSET, -EPERM);
281 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78 282
94bbf1ba 283 bus->bus_client = !!b;
021a1e78
LP
284 return 0;
285}
286
09365592
LP
287_public_ int sd_bus_set_monitor(sd_bus *bus, int b) {
288 assert_return(bus, -EINVAL);
289 assert_return(bus->state == BUS_UNSET, -EPERM);
290 assert_return(!bus_pid_changed(bus), -ECHILD);
291
292 SET_FLAG(bus->hello_flags, KDBUS_HELLO_MONITOR, b);
293 return 0;
294}
295
d9f644e2 296_public_ int sd_bus_negotiate_fds(sd_bus *bus, int b) {
d6888822
LP
297 assert_return(bus, -EINVAL);
298 assert_return(bus->state == BUS_UNSET, -EPERM);
299 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78 300
264ad849
LP
301 SET_FLAG(bus->hello_flags, KDBUS_HELLO_ACCEPT_FD, b);
302 return 0;
303}
304
4fc31988 305_public_ int sd_bus_negotiate_timestamp(sd_bus *bus, int b) {
16be4368
KS
306 assert_return(bus, -EINVAL);
307 assert_return(bus->state == BUS_UNSET, -EPERM);
308 assert_return(!bus_pid_changed(bus), -ECHILD);
309
d21a7bb1 310 SET_FLAG(bus->attach_flags, KDBUS_ATTACH_TIMESTAMP, b);
16be4368
KS
311 return 0;
312}
313
4fc31988 314_public_ int sd_bus_negotiate_creds(sd_bus *bus, uint64_t mask) {
16be4368 315 assert_return(bus, -EINVAL);
95c4fe82 316 assert_return(mask <= _SD_BUS_CREDS_ALL, -EINVAL);
16be4368
KS
317 assert_return(bus->state == BUS_UNSET, -EPERM);
318 assert_return(!bus_pid_changed(bus), -ECHILD);
319
49b832c5 320 /* The well knowns we need unconditionally, so that matches can work */
3310dfd5 321 bus->creds_mask = mask | SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME;
49b832c5 322
ae439c9f 323 return kdbus_translate_attach_flags(bus->creds_mask, &bus->attach_flags);
021a1e78 324}
de1c301e 325
d9f644e2 326_public_ int sd_bus_set_server(sd_bus *bus, int b, sd_id128_t server_id) {
d6888822
LP
327 assert_return(bus, -EINVAL);
328 assert_return(b || sd_id128_equal(server_id, SD_ID128_NULL), -EINVAL);
329 assert_return(bus->state == BUS_UNSET, -EPERM);
330 assert_return(!bus_pid_changed(bus), -ECHILD);
2181a7f5
LP
331
332 bus->is_server = !!b;
98178d39 333 bus->server_id = server_id;
2181a7f5
LP
334 return 0;
335}
336
d9f644e2 337_public_ int sd_bus_set_anonymous(sd_bus *bus, int b) {
d6888822
LP
338 assert_return(bus, -EINVAL);
339 assert_return(bus->state == BUS_UNSET, -EPERM);
340 assert_return(!bus_pid_changed(bus), -ECHILD);
2181a7f5
LP
341
342 bus->anonymous_auth = !!b;
343 return 0;
344}
345
adacb957
LP
346_public_ int sd_bus_set_trusted(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);
350
351 bus->trusted = !!b;
352 return 0;
353}
354
5972fe95
LP
355_public_ int sd_bus_set_name(sd_bus *bus, const char *name) {
356 char *n;
357
358 assert_return(bus, -EINVAL);
359 assert_return(name, -EINVAL);
360 assert_return(bus->state == BUS_UNSET, -EPERM);
361 assert_return(!bus_pid_changed(bus), -ECHILD);
362
363 n = strdup(name);
364 if (!n)
365 return -ENOMEM;
366
367 free(bus->connection_name);
368 bus->connection_name = n;
369
370 return 0;
371}
372
ebcf1f97 373static int hello_callback(sd_bus *bus, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
de1c301e
LP
374 const char *s;
375 int r;
376
377 assert(bus);
c99c09a2 378 assert(bus->state == BUS_HELLO || bus->state == BUS_CLOSING);
de1c301e
LP
379 assert(reply);
380
40ca29a1 381 r = sd_bus_message_get_errno(reply);
eb01ba5d
LP
382 if (r < 0)
383 return r;
40ca29a1
LP
384 if (r > 0)
385 return -r;
eb01ba5d 386
de1c301e
LP
387 r = sd_bus_message_read(reply, "s", &s);
388 if (r < 0)
389 return r;
390
dafb7591
LP
391 if (!service_name_is_valid(s) || s[0] != ':')
392 return -EBADMSG;
393
de1c301e
LP
394 bus->unique_name = strdup(s);
395 if (!bus->unique_name)
396 return -ENOMEM;
397
c99c09a2
LP
398 if (bus->state == BUS_HELLO)
399 bus->state = BUS_RUNNING;
dafb7591 400
de1c301e
LP
401 return 1;
402}
403
404static int bus_send_hello(sd_bus *bus) {
405 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
406 int r;
407
408 assert(bus);
409
6629161f 410 if (!bus->bus_client || bus->is_kernel)
021a1e78
LP
411 return 0;
412
de1c301e
LP
413 r = sd_bus_message_new_method_call(
414 bus,
151b9b96 415 &m,
de1c301e 416 "org.freedesktop.DBus",
a7639e37 417 "/org/freedesktop/DBus",
de1c301e 418 "org.freedesktop.DBus",
151b9b96 419 "Hello");
de1c301e
LP
420 if (r < 0)
421 return r;
422
693eb9a2 423 return sd_bus_call_async(bus, m, hello_callback, NULL, 0, &bus->hello_cookie);
de1c301e
LP
424}
425
a7e3212d 426int bus_start_running(sd_bus *bus) {
de1c301e
LP
427 assert(bus);
428
f08838da 429 if (bus->bus_client && !bus->is_kernel) {
de1c301e 430 bus->state = BUS_HELLO;
e3017af9 431 return 1;
de1c301e
LP
432 }
433
434 bus->state = BUS_RUNNING;
e3017af9 435 return 1;
de1c301e
LP
436}
437
438static int parse_address_key(const char **p, const char *key, char **value) {
821e0756 439 size_t l, n = 0, allocated = 0;
de1c301e
LP
440 const char *a;
441 char *r = NULL;
442
443 assert(p);
444 assert(*p);
de1c301e
LP
445 assert(value);
446
2fd9ae2e
LP
447 if (key) {
448 l = strlen(key);
449 if (strncmp(*p, key, l) != 0)
450 return 0;
de1c301e 451
2fd9ae2e
LP
452 if ((*p)[l] != '=')
453 return 0;
de1c301e 454
2fd9ae2e
LP
455 if (*value)
456 return -EINVAL;
de1c301e 457
2fd9ae2e
LP
458 a = *p + l + 1;
459 } else
460 a = *p;
461
462 while (*a != ';' && *a != ',' && *a != 0) {
821e0756 463 char c;
de1c301e
LP
464
465 if (*a == '%') {
466 int x, y;
467
468 x = unhexchar(a[1]);
469 if (x < 0) {
470 free(r);
471 return x;
472 }
473
474 y = unhexchar(a[2]);
475 if (y < 0) {
476 free(r);
477 return y;
478 }
479
de1c301e 480 c = (char) ((x << 4) | y);
89ffcd2a
LP
481 a += 3;
482 } else {
de1c301e 483 c = *a;
89ffcd2a
LP
484 a++;
485 }
de1c301e 486
821e0756 487 if (!GREEDY_REALLOC(r, allocated, n + 2))
de1c301e 488 return -ENOMEM;
de1c301e 489
de1c301e
LP
490 r[n++] = c;
491 }
492
89ffcd2a
LP
493 if (!r) {
494 r = strdup("");
495 if (!r)
496 return -ENOMEM;
497 } else
498 r[n] = 0;
499
500 if (*a == ',')
501 a++;
502
de1c301e 503 *p = a;
2fd9ae2e
LP
504
505 free(*value);
de1c301e 506 *value = r;
2fd9ae2e 507
de1c301e
LP
508 return 1;
509}
510
511static void skip_address_key(const char **p) {
512 assert(p);
513 assert(*p);
514
89ffcd2a
LP
515 *p += strcspn(*p, ",");
516
517 if (**p == ',')
518 (*p) ++;
de1c301e
LP
519}
520
2fd9ae2e
LP
521static int parse_unix_address(sd_bus *b, const char **p, char **guid) {
522 _cleanup_free_ char *path = NULL, *abstract = NULL;
523 size_t l;
de1c301e
LP
524 int r;
525
526 assert(b);
2fd9ae2e
LP
527 assert(p);
528 assert(*p);
529 assert(guid);
de1c301e 530
2fd9ae2e
LP
531 while (**p != 0 && **p != ';') {
532 r = parse_address_key(p, "guid", guid);
533 if (r < 0)
534 return r;
535 else if (r > 0)
536 continue;
de1c301e 537
2fd9ae2e
LP
538 r = parse_address_key(p, "path", &path);
539 if (r < 0)
540 return r;
541 else if (r > 0)
542 continue;
de1c301e 543
2fd9ae2e
LP
544 r = parse_address_key(p, "abstract", &abstract);
545 if (r < 0)
546 return r;
547 else if (r > 0)
548 continue;
de1c301e 549
2fd9ae2e
LP
550 skip_address_key(p);
551 }
de1c301e 552
2fd9ae2e
LP
553 if (!path && !abstract)
554 return -EINVAL;
de1c301e 555
2fd9ae2e
LP
556 if (path && abstract)
557 return -EINVAL;
558
559 if (path) {
560 l = strlen(path);
561 if (l > sizeof(b->sockaddr.un.sun_path))
562 return -E2BIG;
de1c301e 563
2fd9ae2e
LP
564 b->sockaddr.un.sun_family = AF_UNIX;
565 strncpy(b->sockaddr.un.sun_path, path, sizeof(b->sockaddr.un.sun_path));
566 b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + l;
567 } else if (abstract) {
568 l = strlen(abstract);
569 if (l > sizeof(b->sockaddr.un.sun_path) - 1)
570 return -E2BIG;
571
572 b->sockaddr.un.sun_family = AF_UNIX;
573 b->sockaddr.un.sun_path[0] = 0;
574 strncpy(b->sockaddr.un.sun_path+1, abstract, sizeof(b->sockaddr.un.sun_path)-1);
575 b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + 1 + l;
576 }
577
578 return 0;
579}
580
581static int parse_tcp_address(sd_bus *b, const char **p, char **guid) {
582 _cleanup_free_ char *host = NULL, *port = NULL, *family = NULL;
2fd9ae2e 583 int r;
b92bea5d
ZJS
584 struct addrinfo *result, hints = {
585 .ai_socktype = SOCK_STREAM,
586 .ai_flags = AI_ADDRCONFIG,
587 };
2fd9ae2e
LP
588
589 assert(b);
590 assert(p);
591 assert(*p);
592 assert(guid);
593
594 while (**p != 0 && **p != ';') {
595 r = parse_address_key(p, "guid", guid);
596 if (r < 0)
597 return r;
598 else if (r > 0)
599 continue;
600
601 r = parse_address_key(p, "host", &host);
602 if (r < 0)
603 return r;
604 else if (r > 0)
605 continue;
606
607 r = parse_address_key(p, "port", &port);
608 if (r < 0)
609 return r;
610 else if (r > 0)
611 continue;
612
613 r = parse_address_key(p, "family", &family);
614 if (r < 0)
615 return r;
616 else if (r > 0)
617 continue;
618
619 skip_address_key(p);
620 }
621
622 if (!host || !port)
623 return -EINVAL;
624
2fd9ae2e
LP
625 if (family) {
626 if (streq(family, "ipv4"))
627 hints.ai_family = AF_INET;
628 else if (streq(family, "ipv6"))
629 hints.ai_family = AF_INET6;
630 else
631 return -EINVAL;
632 }
633
634 r = getaddrinfo(host, port, &hints, &result);
635 if (r == EAI_SYSTEM)
636 return -errno;
637 else if (r != 0)
638 return -EADDRNOTAVAIL;
639
640 memcpy(&b->sockaddr, result->ai_addr, result->ai_addrlen);
641 b->sockaddr_size = result->ai_addrlen;
642
643 freeaddrinfo(result);
644
645 return 0;
646}
647
648static int parse_exec_address(sd_bus *b, const char **p, char **guid) {
649 char *path = NULL;
650 unsigned n_argv = 0, j;
651 char **argv = NULL;
821e0756 652 size_t allocated = 0;
2fd9ae2e
LP
653 int r;
654
655 assert(b);
656 assert(p);
657 assert(*p);
658 assert(guid);
659
660 while (**p != 0 && **p != ';') {
661 r = parse_address_key(p, "guid", guid);
662 if (r < 0)
663 goto fail;
664 else if (r > 0)
665 continue;
666
667 r = parse_address_key(p, "path", &path);
668 if (r < 0)
669 goto fail;
670 else if (r > 0)
671 continue;
672
673 if (startswith(*p, "argv")) {
674 unsigned ul;
675
676 errno = 0;
677 ul = strtoul(*p + 4, (char**) p, 10);
8333c77e 678 if (errno > 0 || **p != '=' || ul > 256) {
2fd9ae2e
LP
679 r = -EINVAL;
680 goto fail;
681 }
682
683 (*p) ++;
684
685 if (ul >= n_argv) {
821e0756 686 if (!GREEDY_REALLOC0(argv, allocated, ul + 2)) {
2fd9ae2e
LP
687 r = -ENOMEM;
688 goto fail;
689 }
690
2fd9ae2e
LP
691 n_argv = ul + 1;
692 }
693
694 r = parse_address_key(p, NULL, argv + ul);
de1c301e 695 if (r < 0)
2fd9ae2e 696 goto fail;
de1c301e 697
2fd9ae2e 698 continue;
de1c301e
LP
699 }
700
2fd9ae2e
LP
701 skip_address_key(p);
702 }
de1c301e 703
5a0f6033
LP
704 if (!path) {
705 r = -EINVAL;
2fd9ae2e 706 goto fail;
5a0f6033 707 }
de1c301e 708
2fd9ae2e
LP
709 /* Make sure there are no holes in the array, with the
710 * exception of argv[0] */
711 for (j = 1; j < n_argv; j++)
712 if (!argv[j]) {
713 r = -EINVAL;
714 goto fail;
715 }
716
717 if (argv && argv[0] == NULL) {
718 argv[0] = strdup(path);
719 if (!argv[0]) {
720 r = -ENOMEM;
721 goto fail;
722 }
723 }
de1c301e 724
2fd9ae2e
LP
725 b->exec_path = path;
726 b->exec_argv = argv;
727 return 0;
de1c301e 728
2fd9ae2e
LP
729fail:
730 for (j = 0; j < n_argv; j++)
731 free(argv[j]);
732
733 free(argv);
734 free(path);
735 return r;
736}
737
6629161f
LP
738static int parse_kernel_address(sd_bus *b, const char **p, char **guid) {
739 _cleanup_free_ char *path = NULL;
740 int r;
741
742 assert(b);
743 assert(p);
744 assert(*p);
745 assert(guid);
746
747 while (**p != 0 && **p != ';') {
748 r = parse_address_key(p, "guid", guid);
749 if (r < 0)
750 return r;
751 else if (r > 0)
752 continue;
753
754 r = parse_address_key(p, "path", &path);
755 if (r < 0)
756 return r;
757 else if (r > 0)
758 continue;
759
760 skip_address_key(p);
761 }
762
763 if (!path)
764 return -EINVAL;
765
766 free(b->kernel);
767 b->kernel = path;
768 path = NULL;
769
770 return 0;
771}
772
bc9fd78c 773static int parse_container_unix_address(sd_bus *b, const char **p, char **guid) {
a7893c6b
LP
774 _cleanup_free_ char *machine = NULL;
775 int r;
776
777 assert(b);
778 assert(p);
779 assert(*p);
780 assert(guid);
781
782 while (**p != 0 && **p != ';') {
783 r = parse_address_key(p, "guid", guid);
784 if (r < 0)
785 return r;
786 else if (r > 0)
787 continue;
788
789 r = parse_address_key(p, "machine", &machine);
790 if (r < 0)
791 return r;
792 else if (r > 0)
793 continue;
794
795 skip_address_key(p);
796 }
797
798 if (!machine)
799 return -EINVAL;
800
b6741478
LP
801 if (!filename_is_safe(machine))
802 return -EINVAL;
803
a7893c6b
LP
804 free(b->machine);
805 b->machine = machine;
806 machine = NULL;
807
808 b->sockaddr.un.sun_family = AF_UNIX;
df1e0204
LP
809 strncpy(b->sockaddr.un.sun_path, "/var/run/dbus/system_bus_socket", sizeof(b->sockaddr.un.sun_path));
810 b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + strlen("/var/run/dbus/system_bus_socket");
a7893c6b
LP
811
812 return 0;
813}
814
bc9fd78c
LP
815static int parse_container_kernel_address(sd_bus *b, const char **p, char **guid) {
816 _cleanup_free_ char *machine = NULL;
817 int r;
818
819 assert(b);
820 assert(p);
821 assert(*p);
822 assert(guid);
823
824 while (**p != 0 && **p != ';') {
825 r = parse_address_key(p, "guid", guid);
826 if (r < 0)
827 return r;
828 else if (r > 0)
829 continue;
830
831 r = parse_address_key(p, "machine", &machine);
832 if (r < 0)
833 return r;
834 else if (r > 0)
835 continue;
836
837 skip_address_key(p);
838 }
839
840 if (!machine)
841 return -EINVAL;
842
843 if (!filename_is_safe(machine))
844 return -EINVAL;
845
846 free(b->machine);
847 b->machine = machine;
848 machine = NULL;
849
850 free(b->kernel);
851 b->kernel = strdup("/dev/kdbus/0-system/bus");
852 if (!b->kernel)
853 return -ENOMEM;
854
855 return 0;
856}
857
2fd9ae2e
LP
858static void bus_reset_parsed_address(sd_bus *b) {
859 assert(b);
860
861 zero(b->sockaddr);
862 b->sockaddr_size = 0;
863 strv_free(b->exec_argv);
864 free(b->exec_path);
865 b->exec_path = NULL;
866 b->exec_argv = NULL;
98178d39 867 b->server_id = SD_ID128_NULL;
6629161f
LP
868 free(b->kernel);
869 b->kernel = NULL;
a7893c6b
LP
870 free(b->machine);
871 b->machine = NULL;
2fd9ae2e
LP
872}
873
874static int bus_parse_next_address(sd_bus *b) {
875 _cleanup_free_ char *guid = NULL;
876 const char *a;
877 int r;
878
879 assert(b);
880
881 if (!b->address)
882 return 0;
883 if (b->address[b->address_index] == 0)
884 return 0;
885
886 bus_reset_parsed_address(b);
887
888 a = b->address + b->address_index;
de1c301e 889
2fd9ae2e 890 while (*a != 0) {
de1c301e 891
2fd9ae2e
LP
892 if (*a == ';') {
893 a++;
894 continue;
de1c301e
LP
895 }
896
2fd9ae2e
LP
897 if (startswith(a, "unix:")) {
898 a += 5;
de1c301e 899
2fd9ae2e 900 r = parse_unix_address(b, &a, &guid);
de1c301e
LP
901 if (r < 0)
902 return r;
2fd9ae2e 903 break;
de1c301e 904
2fd9ae2e 905 } else if (startswith(a, "tcp:")) {
de1c301e 906
2fd9ae2e
LP
907 a += 4;
908 r = parse_tcp_address(b, &a, &guid);
de1c301e
LP
909 if (r < 0)
910 return r;
de1c301e 911
2fd9ae2e
LP
912 break;
913
914 } else if (startswith(a, "unixexec:")) {
915
916 a += 9;
917 r = parse_exec_address(b, &a, &guid);
de1c301e
LP
918 if (r < 0)
919 return r;
de1c301e 920
2fd9ae2e 921 break;
de1c301e 922
6629161f
LP
923 } else if (startswith(a, "kernel:")) {
924
925 a += 7;
926 r = parse_kernel_address(b, &a, &guid);
927 if (r < 0)
928 return r;
929
a7893c6b 930 break;
bc9fd78c
LP
931 } else if (startswith(a, "x-container-unix:")) {
932
933 a += 17;
934 r = parse_container_unix_address(b, &a, &guid);
935 if (r < 0)
936 return r;
937
938 break;
939 } else if (startswith(a, "x-container-kernel:")) {
a7893c6b 940
bc9fd78c
LP
941 a += 19;
942 r = parse_container_kernel_address(b, &a, &guid);
a7893c6b
LP
943 if (r < 0)
944 return r;
945
6629161f 946 break;
de1c301e
LP
947 }
948
2fd9ae2e
LP
949 a = strchr(a, ';');
950 if (!a)
951 return 0;
de1c301e
LP
952 }
953
954 if (guid) {
98178d39 955 r = sd_id128_from_string(guid, &b->server_id);
de1c301e
LP
956 if (r < 0)
957 return r;
958 }
959
2fd9ae2e 960 b->address_index = a - b->address;
de1c301e
LP
961 return 1;
962}
963
a7e3212d 964static int bus_start_address(sd_bus *b) {
2fd9ae2e
LP
965 int r;
966
967 assert(b);
968
969 for (;;) {
1e05d493 970 bool skipped = false;
2fd9ae2e 971
1e05d493 972 bus_close_fds(b);
a7e3212d 973
1e05d493 974 if (b->exec_path)
a7893c6b 975 r = bus_socket_exec(b);
bc9fd78c
LP
976 else if (b->machine && b->kernel)
977 r = bus_container_connect_kernel(b);
978 else if (b->machine && b->sockaddr.sa.sa_family != AF_UNSPEC)
979 r = bus_container_connect_socket(b);
1e05d493 980 else if (b->kernel)
a7893c6b 981 r = bus_kernel_connect(b);
1e05d493 982 else if (b->sockaddr.sa.sa_family != AF_UNSPEC)
a7893c6b 983 r = bus_socket_connect(b);
1e05d493
LP
984 else
985 skipped = true;
986
987 if (!skipped) {
988 if (r >= 0) {
989 r = attach_io_events(b);
990 if (r >= 0)
991 return r;
992 }
6629161f 993
2fd9ae2e
LP
994 b->last_connect_error = -r;
995 }
996
997 r = bus_parse_next_address(b);
998 if (r < 0)
999 return r;
1000 if (r == 0)
1001 return b->last_connect_error ? -b->last_connect_error : -ECONNREFUSED;
de1c301e
LP
1002 }
1003}
1004
a7e3212d
LP
1005int bus_next_address(sd_bus *b) {
1006 assert(b);
1007
1008 bus_reset_parsed_address(b);
1009 return bus_start_address(b);
1010}
1011
021a1e78 1012static int bus_start_fd(sd_bus *b) {
6629161f 1013 struct stat st;
021a1e78
LP
1014 int r;
1015
1016 assert(b);
e82c9509
LP
1017 assert(b->input_fd >= 0);
1018 assert(b->output_fd >= 0);
021a1e78 1019
e82c9509 1020 r = fd_nonblock(b->input_fd, true);
021a1e78
LP
1021 if (r < 0)
1022 return r;
1023
e82c9509 1024 r = fd_cloexec(b->input_fd, true);
021a1e78
LP
1025 if (r < 0)
1026 return r;
1027
e82c9509
LP
1028 if (b->input_fd != b->output_fd) {
1029 r = fd_nonblock(b->output_fd, true);
1030 if (r < 0)
1031 return r;
1032
1033 r = fd_cloexec(b->output_fd, true);
1034 if (r < 0)
1035 return r;
1036 }
1037
6629161f
LP
1038 if (fstat(b->input_fd, &st) < 0)
1039 return -errno;
1040
1041 if (S_ISCHR(b->input_fd))
1042 return bus_kernel_take_fd(b);
1043 else
1044 return bus_socket_take_fd(b);
021a1e78
LP
1045}
1046
d9f644e2 1047_public_ int sd_bus_start(sd_bus *bus) {
021a1e78
LP
1048 int r;
1049
d6888822
LP
1050 assert_return(bus, -EINVAL);
1051 assert_return(bus->state == BUS_UNSET, -EPERM);
1052 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78
LP
1053
1054 bus->state = BUS_OPENING;
1055
2181a7f5
LP
1056 if (bus->is_server && bus->bus_client)
1057 return -EINVAL;
1058
e82c9509 1059 if (bus->input_fd >= 0)
021a1e78 1060 r = bus_start_fd(bus);
a7893c6b 1061 else if (bus->address || bus->sockaddr.sa.sa_family != AF_UNSPEC || bus->exec_path || bus->kernel || bus->machine)
a7e3212d 1062 r = bus_start_address(bus);
021a1e78
LP
1063 else
1064 return -EINVAL;
1065
1066 if (r < 0)
1067 return r;
1068
1069 return bus_send_hello(bus);
1070}
1071
af08d2f9
LP
1072_public_ int sd_bus_open(sd_bus **ret) {
1073 const char *e;
1074 sd_bus *b;
1075 int r;
1076
1077 assert_return(ret, -EINVAL);
1078
1079 /* Let's connect to the starter bus if it is set, and
1080 * otherwise to the bus that is appropropriate for the scope
1081 * we are running in */
1082
1083 e = secure_getenv("DBUS_STARTER_BUS_TYPE");
1084 if (e) {
1085 if (streq(e, "system"))
1086 return sd_bus_open_system(ret);
09365592 1087 else if (STR_IN_SET(e, "session", "user"))
af08d2f9
LP
1088 return sd_bus_open_user(ret);
1089 }
1090
1091 e = secure_getenv("DBUS_STARTER_ADDRESS");
1092 if (!e) {
1093 if (cg_pid_get_owner_uid(0, NULL) >= 0)
1094 return sd_bus_open_user(ret);
1095 else
1096 return sd_bus_open_system(ret);
1097 }
1098
1099 r = sd_bus_new(&b);
1100 if (r < 0)
1101 return r;
1102
1103 r = sd_bus_set_address(b, e);
1104 if (r < 0)
1105 goto fail;
1106
1107 b->bus_client = true;
1108
1109 /* We don't know whether the bus is trusted or not, so better
1110 * be safe, and authenticate everything */
1111 b->trusted = false;
1112 b->attach_flags |= KDBUS_ATTACH_CAPS | KDBUS_ATTACH_CREDS;
1113
1114 r = sd_bus_start(b);
1115 if (r < 0)
1116 goto fail;
1117
1118 *ret = b;
1119 return 0;
1120
1121fail:
1122 bus_free(b);
1123 return r;
1124}
1125
09365592 1126int bus_set_address_system(sd_bus *b) {
de1c301e 1127 const char *e;
09365592
LP
1128 assert(b);
1129
1130 e = secure_getenv("DBUS_SYSTEM_BUS_ADDRESS");
1131 if (e)
1132 return sd_bus_set_address(b, e);
1133
1134 return sd_bus_set_address(b, DEFAULT_SYSTEM_BUS_PATH);
1135}
1136
1137_public_ int sd_bus_open_system(sd_bus **ret) {
de1c301e
LP
1138 sd_bus *b;
1139 int r;
1140
d6888822 1141 assert_return(ret, -EINVAL);
de1c301e 1142
021a1e78
LP
1143 r = sd_bus_new(&b);
1144 if (r < 0)
1145 return r;
1146
09365592 1147 r = bus_set_address_system(b);
e3dd987c
LP
1148 if (r < 0)
1149 goto fail;
de1c301e 1150
94bbf1ba 1151 b->bus_client = true;
5972fe95 1152 b->is_system = true;
021a1e78 1153
adacb957
LP
1154 /* Let's do per-method access control on the system bus. We
1155 * need the caller's UID and capability set for that. */
1156 b->trusted = false;
1157 b->attach_flags |= KDBUS_ATTACH_CAPS | KDBUS_ATTACH_CREDS;
1158
021a1e78
LP
1159 r = sd_bus_start(b);
1160 if (r < 0)
1161 goto fail;
de1c301e
LP
1162
1163 *ret = b;
1164 return 0;
021a1e78
LP
1165
1166fail:
1167 bus_free(b);
1168 return r;
de1c301e
LP
1169}
1170
09365592 1171int bus_set_address_user(sd_bus *b) {
de1c301e 1172 const char *e;
de1c301e 1173
09365592 1174 assert(b);
021a1e78 1175
6c03089c 1176 e = secure_getenv("DBUS_SESSION_BUS_ADDRESS");
09365592
LP
1177 if (e)
1178 return sd_bus_set_address(b, e);
1179
1180 e = secure_getenv("XDG_RUNTIME_DIR");
de1c301e 1181 if (e) {
09365592 1182 _cleanup_free_ char *ee = NULL;
e3dd987c 1183
09365592
LP
1184 ee = bus_address_escape(e);
1185 if (!ee)
1186 return -ENOMEM;
e3dd987c 1187
626851be 1188#ifdef ENABLE_KDBUS
09365592 1189 asprintf(&b->address, KERNEL_USER_BUS_FMT ";" UNIX_USER_BUS_FMT, (unsigned long) getuid(), ee);
626851be 1190#else
09365592 1191 asprintf(&b->address, UNIX_USER_BUS_FMT, ee);
626851be 1192#endif
09365592 1193 } else {
626851be 1194#ifdef ENABLE_KDBUS
09365592 1195 asprintf(&b->address, KERNEL_USER_BUS_FMT, (unsigned long) getuid());
626851be 1196#else
09365592 1197 return -ECONNREFUSED;
626851be 1198#endif
de1c301e
LP
1199 }
1200
09365592
LP
1201 if (!b->address)
1202 return -ENOMEM;
1203
1204 return 0;
1205}
1206
1207_public_ int sd_bus_open_user(sd_bus **ret) {
1208 sd_bus *b;
1209 int r;
1210
1211 assert_return(ret, -EINVAL);
1212
1213 r = sd_bus_new(&b);
1214 if (r < 0)
1215 return r;
1216
1217 r = bus_set_address_user(b);
1218 if (r < 0)
1219 return r;
1220
94bbf1ba 1221 b->bus_client = true;
5972fe95 1222 b->is_user = true;
de1c301e 1223
adacb957
LP
1224 /* We don't do any per-method access control on the user
1225 * bus. */
1226 b->trusted = true;
1227
021a1e78 1228 r = sd_bus_start(b);
2571ead1
LP
1229 if (r < 0)
1230 goto fail;
de1c301e
LP
1231
1232 *ret = b;
1233 return 0;
2571ead1
LP
1234
1235fail:
021a1e78 1236 bus_free(b);
2571ead1 1237 return r;
de1c301e
LP
1238}
1239
09365592 1240int bus_set_address_system_remote(sd_bus *b, const char *host) {
0f8bd8de 1241 _cleanup_free_ char *e = NULL;
0f8bd8de 1242
09365592
LP
1243 assert(b);
1244 assert(host);
0f8bd8de
LP
1245
1246 e = bus_address_escape(host);
1247 if (!e)
1248 return -ENOMEM;
1249
09365592
LP
1250 b->address = strjoin("unixexec:path=ssh,argv1=-xT,argv2=", e, ",argv3=systemd-stdio-bridge", NULL);
1251 if (!b->address)
0f8bd8de 1252 return -ENOMEM;
a7893c6b 1253
09365592
LP
1254 return 0;
1255 }
1256
1257_public_ int sd_bus_open_system_remote(sd_bus **ret, const char *host) {
1258 sd_bus *bus;
1259 int r;
1260
1261 assert_return(host, -EINVAL);
1262 assert_return(ret, -EINVAL);
1263
a7893c6b 1264 r = sd_bus_new(&bus);
09365592 1265 if (r < 0)
a7893c6b 1266 return r;
a7893c6b 1267
09365592
LP
1268 r = bus_set_address_system_remote(bus, host);
1269 if (r < 0)
1270 goto fail;
1271
a7893c6b 1272 bus->bus_client = true;
09365592 1273 bus->trusted = false;
a7893c6b
LP
1274
1275 r = sd_bus_start(bus);
09365592
LP
1276 if (r < 0)
1277 goto fail;
a7893c6b
LP
1278
1279 *ret = bus;
1280 return 0;
09365592
LP
1281
1282fail:
1283 bus_free(bus);
1284 return r;
a7893c6b
LP
1285}
1286
09365592 1287int bus_set_address_system_container(sd_bus *b, const char *machine) {
a7893c6b 1288 _cleanup_free_ char *e = NULL;
a7893c6b 1289
09365592
LP
1290 assert(b);
1291 assert(machine);
a7893c6b
LP
1292
1293 e = bus_address_escape(machine);
1294 if (!e)
1295 return -ENOMEM;
1296
9e554864 1297#ifdef ENABLE_KDBUS
09365592 1298 b->address = strjoin("x-container-kernel:machine=", e, ";x-container-unix:machine=", e, NULL);
9e554864 1299#else
09365592 1300 b->address = strjoin("x-container-unix:machine=", e, NULL);
9e554864 1301#endif
09365592 1302 if (!b->address)
a7893c6b 1303 return -ENOMEM;
0f8bd8de 1304
09365592
LP
1305 return 0;
1306}
1307
1308_public_ int sd_bus_open_system_container(sd_bus **ret, const char *machine) {
1309 sd_bus *bus;
1310 int r;
1311
1312 assert_return(machine, -EINVAL);
1313 assert_return(ret, -EINVAL);
1314 assert_return(filename_is_safe(machine), -EINVAL);
1315
0f8bd8de 1316 r = sd_bus_new(&bus);
09365592 1317 if (r < 0)
0f8bd8de 1318 return r;
0f8bd8de 1319
09365592
LP
1320 r = bus_set_address_system_container(bus, machine);
1321 if (r < 0)
1322 goto fail;
1323
0f8bd8de 1324 bus->bus_client = true;
09365592 1325 bus->trusted = false;
0f8bd8de
LP
1326
1327 r = sd_bus_start(bus);
09365592
LP
1328 if (r < 0)
1329 goto fail;
0f8bd8de
LP
1330
1331 *ret = bus;
1332 return 0;
09365592
LP
1333
1334fail:
1335 bus_free(bus);
1336 return r;
0f8bd8de
LP
1337}
1338
d9f644e2 1339_public_ void sd_bus_close(sd_bus *bus) {
0e586eae 1340
de1c301e
LP
1341 if (!bus)
1342 return;
d5a2b9a6
LP
1343 if (bus->state == BUS_CLOSED)
1344 return;
1345 if (bus_pid_changed(bus))
f54514f3
LP
1346 return;
1347
1348 bus->state = BUS_CLOSED;
e82c9509 1349
40ca29a1
LP
1350 sd_bus_detach_event(bus);
1351
0e586eae
LP
1352 /* Drop all queued messages so that they drop references to
1353 * the bus object and the bus may be freed */
1354 bus_reset_queues(bus);
1355
f54514f3
LP
1356 if (!bus->is_kernel)
1357 bus_close_fds(bus);
1358
1359 /* We'll leave the fd open in case this is a kernel bus, since
1360 * there might still be memblocks around that reference this
cd6d5e1c 1361 * bus, and they might need to invoke the KDBUS_CMD_FREE
1d0e3c98 1362 * ioctl on the fd when they are freed. */
de1c301e
LP
1363}
1364
718db961
LP
1365static void bus_enter_closing(sd_bus *bus) {
1366 assert(bus);
1367
1368 if (bus->state != BUS_OPENING &&
1369 bus->state != BUS_AUTHENTICATING &&
1370 bus->state != BUS_HELLO &&
1371 bus->state != BUS_RUNNING)
1372 return;
1373
1374 bus->state = BUS_CLOSING;
1375}
1376
d9f644e2 1377_public_ sd_bus *sd_bus_ref(sd_bus *bus) {
9d6c7c82 1378 assert_return(bus, NULL);
de1c301e 1379
e4ee6e5c 1380 assert_se(REFCNT_INC(bus->n_ref) >= 2);
de1c301e 1381
de1c301e
LP
1382 return bus;
1383}
1384
d9f644e2 1385_public_ sd_bus *sd_bus_unref(sd_bus *bus) {
b7fc42e0 1386 unsigned i;
5b1bc83f
LP
1387
1388 if (!bus)
1389 return NULL;
de1c301e 1390
f389bf15
LP
1391 if (REFCNT_GET(bus->n_ref) == bus->rqueue_size + bus->wqueue_size + 1) {
1392 bool q = true;
b7fc42e0 1393
f389bf15
LP
1394 for (i = 0; i < bus->rqueue_size; i++)
1395 if (bus->rqueue[i]->n_ref > 1) {
1396 q = false;
1397 break;
1398 }
b7fc42e0 1399
f389bf15
LP
1400 if (q) {
1401 for (i = 0; i < bus->wqueue_size; i++)
1402 if (bus->wqueue[i]->n_ref > 1) {
1403 q = false;
1404 break;
1405 }
1406 }
b7fc42e0 1407
f389bf15
LP
1408 /* We are the only holders on the messages, and the
1409 * messages are the only holders on us, so let's drop
1410 * the messages and thus implicitly also kill our own
1411 * last references */
1412
23abf5d5
LP
1413 if (q)
1414 bus_reset_queues(bus);
f389bf15 1415 }
de1c301e 1416
f389bf15
LP
1417 i = REFCNT_DEC(bus->n_ref);
1418 if (i > 0)
1419 return NULL;
1420
1421 bus_free(bus);
de1c301e
LP
1422 return NULL;
1423}
1424
d9f644e2 1425_public_ int sd_bus_is_open(sd_bus *bus) {
d6888822
LP
1426
1427 assert_return(bus, -EINVAL);
1428 assert_return(!bus_pid_changed(bus), -ECHILD);
e3017af9 1429
f54514f3 1430 return BUS_IS_OPEN(bus->state);
e3017af9
LP
1431}
1432
d9f644e2 1433_public_ int sd_bus_can_send(sd_bus *bus, char type) {
d728d708
LP
1434 int r;
1435
d6888822
LP
1436 assert_return(bus, -EINVAL);
1437 assert_return(bus->state != BUS_UNSET, -ENOTCONN);
1438 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 1439
09365592
LP
1440 if (bus->hello_flags & KDBUS_HELLO_MONITOR)
1441 return 0;
1442
d728d708 1443 if (type == SD_BUS_TYPE_UNIX_FD) {
264ad849 1444 if (!(bus->hello_flags & KDBUS_HELLO_ACCEPT_FD))
021a1e78
LP
1445 return 0;
1446
20902f3e 1447 r = bus_ensure_running(bus);
d728d708
LP
1448 if (r < 0)
1449 return r;
de1c301e 1450
d728d708
LP
1451 return bus->can_fds;
1452 }
1453
1454 return bus_type_is_valid(type);
de1c301e
LP
1455}
1456
d9f644e2 1457_public_ int sd_bus_get_server_id(sd_bus *bus, sd_id128_t *server_id) {
d728d708 1458 int r;
de1c301e 1459
d6888822
LP
1460 assert_return(bus, -EINVAL);
1461 assert_return(server_id, -EINVAL);
1462 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 1463
20902f3e 1464 r = bus_ensure_running(bus);
d728d708
LP
1465 if (r < 0)
1466 return r;
de1c301e 1467
98178d39 1468 *server_id = bus->server_id;
d728d708 1469 return 0;
de1c301e
LP
1470}
1471
3df7a7e6 1472static int bus_seal_message(sd_bus *b, sd_bus_message *m, usec_t timeout) {
7adc46fc 1473 assert(b);
de1c301e
LP
1474 assert(m);
1475
aea93deb
LP
1476 if (m->sealed) {
1477 /* If we copy the same message to multiple
693eb9a2 1478 * destinations, avoid using the same cookie
aea93deb 1479 * numbers. */
693eb9a2 1480 b->cookie = MAX(b->cookie, BUS_MESSAGE_COOKIE(m));
de1c301e 1481 return 0;
aea93deb 1482 }
de1c301e 1483
3df7a7e6
LP
1484 if (timeout == 0)
1485 timeout = BUS_DEFAULT_TIMEOUT;
1486
693eb9a2 1487 return bus_message_seal(m, ++b->cookie, timeout);
de1c301e
LP
1488}
1489
e1c433c6
LP
1490static int bus_remarshal_message(sd_bus *b, sd_bus_message **m) {
1491 assert(b);
1492
6f285378 1493 /* Do packet version and endianness already match? */
e1c433c6
LP
1494 if ((b->message_version == 0 || b->message_version == (*m)->header->version) &&
1495 (b->message_endian == 0 || b->message_endian == (*m)->header->endian))
1496 return 0;
1497
1498 /* No? Then remarshal! */
1499 return bus_message_remarshal(b, m);
1500}
1501
7adc46fc
LP
1502int bus_seal_synthetic_message(sd_bus *b, sd_bus_message *m) {
1503 assert(b);
1504 assert(m);
1505
7adc46fc
LP
1506 /* The bus specification says the serial number cannot be 0,
1507 * hence let's fill something in for synthetic messages. Since
1508 * synthetic messages might have a fake sender and we don't
1509 * want to interfere with the real sender's serial numbers we
6f285378 1510 * pick a fixed, artificial one. We use (uint32_t) -1 rather
7adc46fc
LP
1511 * than (uint64_t) -1 since dbus1 only had 32bit identifiers,
1512 * even though kdbus can do 64bit. */
1513
3df7a7e6 1514 return bus_message_seal(m, 0xFFFFFFFFULL, 0);
7adc46fc
LP
1515}
1516
069f5e61 1517static int bus_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call, size_t *idx) {
2e3db52d
LP
1518 int r;
1519
718db961 1520 assert(bus);
2e3db52d 1521 assert(m);
718db961
LP
1522
1523 if (bus->is_kernel)
069f5e61 1524 r = bus_kernel_write_message(bus, m, hint_sync_call);
718db961 1525 else
2e3db52d
LP
1526 r = bus_socket_write_message(bus, m, idx);
1527
1528 if (r <= 0)
1529 return r;
1530
90911bb6 1531 if (bus->is_kernel || *idx >= BUS_MESSAGE_SIZE(m))
42c4ebcb 1532 log_debug("Sent message type=%s sender=%s destination=%s object=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " error=%s",
2e3db52d
LP
1533 bus_message_type_to_string(m->header->type),
1534 strna(sd_bus_message_get_sender(m)),
1535 strna(sd_bus_message_get_destination(m)),
1536 strna(sd_bus_message_get_path(m)),
1537 strna(sd_bus_message_get_interface(m)),
1538 strna(sd_bus_message_get_member(m)),
42c4ebcb
LP
1539 BUS_MESSAGE_COOKIE(m),
1540 m->reply_cookie,
2e3db52d
LP
1541 strna(m->error.message));
1542
1543 return r;
718db961
LP
1544}
1545
de1c301e 1546static int dispatch_wqueue(sd_bus *bus) {
e3017af9 1547 int r, ret = 0;
de1c301e
LP
1548
1549 assert(bus);
89ffcd2a 1550 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
de1c301e 1551
de1c301e
LP
1552 while (bus->wqueue_size > 0) {
1553
069f5e61 1554 r = bus_write_message(bus, bus->wqueue[0], false, &bus->windex);
718db961 1555 if (r < 0)
de1c301e 1556 return r;
718db961 1557 else if (r == 0)
e3017af9
LP
1558 /* Didn't do anything this time */
1559 return ret;
6629161f 1560 else if (bus->is_kernel || bus->windex >= BUS_MESSAGE_SIZE(bus->wqueue[0])) {
de1c301e
LP
1561 /* Fully written. Let's drop the entry from
1562 * the queue.
1563 *
1564 * This isn't particularly optimized, but
1565 * well, this is supposed to be our worst-case
1566 * buffer only, and the socket buffer is
1567 * supposed to be our primary buffer, and if
1568 * it got full, then all bets are off
1569 * anyway. */
1570
de1c301e 1571 bus->wqueue_size --;
c4e6e242 1572 sd_bus_message_unref(bus->wqueue[0]);
de1c301e
LP
1573 memmove(bus->wqueue, bus->wqueue + 1, sizeof(sd_bus_message*) * bus->wqueue_size);
1574 bus->windex = 0;
1575
e3017af9 1576 ret = 1;
de1c301e
LP
1577 }
1578 }
1579
e3017af9 1580 return ret;
de1c301e
LP
1581}
1582
766c5809 1583static int bus_read_message(sd_bus *bus, bool hint_priority, int64_t priority) {
7d22c717
LP
1584 assert(bus);
1585
1586 if (bus->is_kernel)
766c5809 1587 return bus_kernel_read_message(bus, hint_priority, priority);
7d22c717
LP
1588 else
1589 return bus_socket_read_message(bus);
1590}
1591
7adc46fc 1592int bus_rqueue_make_room(sd_bus *bus) {
821e0756 1593 assert(bus);
7d22c717 1594
821e0756 1595 if (bus->rqueue_size >= BUS_RQUEUE_MAX)
7d22c717
LP
1596 return -ENOBUFS;
1597
821e0756 1598 if (!GREEDY_REALLOC(bus->rqueue, bus->rqueue_allocated, bus->rqueue_size + 1))
7d22c717
LP
1599 return -ENOMEM;
1600
7d22c717
LP
1601 return 0;
1602}
1603
766c5809 1604static int dispatch_rqueue(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **m) {
e3017af9 1605 int r, ret = 0;
de1c301e
LP
1606
1607 assert(bus);
1608 assert(m);
89ffcd2a 1609 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
de1c301e 1610
766c5809
LP
1611 /* Note that the priority logic is only available on kdbus,
1612 * where the rqueue is unused. We check the rqueue here
1613 * anyway, because it's simple... */
1614
7d22c717
LP
1615 for (;;) {
1616 if (bus->rqueue_size > 0) {
1617 /* Dispatch a queued message */
de1c301e 1618
7d22c717
LP
1619 *m = bus->rqueue[0];
1620 bus->rqueue_size --;
1621 memmove(bus->rqueue, bus->rqueue + 1, sizeof(sd_bus_message*) * bus->rqueue_size);
1622 return 1;
1623 }
de1c301e 1624
7d22c717 1625 /* Try to read a new message */
766c5809 1626 r = bus_read_message(bus, hint_priority, priority);
718db961 1627 if (r < 0)
e3017af9 1628 return r;
e3017af9
LP
1629 if (r == 0)
1630 return ret;
de1c301e 1631
2e8d788c 1632 ret = 1;
7d22c717 1633 }
de1c301e
LP
1634}
1635
069f5e61 1636static int bus_send_internal(sd_bus *bus, sd_bus_message *_m, uint64_t *cookie, bool hint_sync_call) {
e1c433c6 1637 _cleanup_bus_message_unref_ sd_bus_message *m = sd_bus_message_ref(_m);
de1c301e
LP
1638 int r;
1639
d6888822
LP
1640 assert_return(bus, -EINVAL);
1641 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
1642 assert_return(m, -EINVAL);
1643 assert_return(!bus_pid_changed(bus), -ECHILD);
09365592 1644 assert_return(!bus->is_kernel || !(bus->hello_flags & KDBUS_HELLO_MONITOR), -EROFS);
021a1e78
LP
1645
1646 if (m->n_fds > 0) {
1647 r = sd_bus_can_send(bus, SD_BUS_TYPE_UNIX_FD);
1648 if (r < 0)
1649 return r;
1650 if (r == 0)
1651 return -ENOTSUP;
1652 }
de1c301e 1653
693eb9a2 1654 /* If the cookie number isn't kept, then we know that no reply
29f6aadd 1655 * is expected */
693eb9a2 1656 if (!cookie && !m->sealed)
0461f8cd 1657 m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
29f6aadd 1658
3df7a7e6 1659 r = bus_seal_message(bus, m, 0);
de1c301e
LP
1660 if (r < 0)
1661 return r;
1662
441d56a1 1663 /* Remarshall if we have to. This will possibly unref the
e1c433c6
LP
1664 * message and place a replacement in m */
1665 r = bus_remarshal_message(bus, &m);
1666 if (r < 0)
1667 return r;
1668
5407f2de
LP
1669 /* If this is a reply and no reply was requested, then let's
1670 * suppress this, if we can */
693eb9a2 1671 if (m->dont_send && !cookie)
7a37d625 1672 return 1;
5407f2de 1673
89ffcd2a 1674 if ((bus->state == BUS_RUNNING || bus->state == BUS_HELLO) && bus->wqueue_size <= 0) {
de1c301e
LP
1675 size_t idx = 0;
1676
069f5e61 1677 r = bus_write_message(bus, m, hint_sync_call, &idx);
32f46480 1678 if (r < 0) {
441d56a1 1679 if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
32f46480 1680 bus_enter_closing(bus);
441d56a1
LP
1681 return -ECONNRESET;
1682 }
32f46480 1683
de1c301e 1684 return r;
32f46480 1685 } else if (!bus->is_kernel && idx < BUS_MESSAGE_SIZE(m)) {
de1c301e
LP
1686 /* Wasn't fully written. So let's remember how
1687 * much was written. Note that the first entry
1688 * of the wqueue array is always allocated so
1689 * that we always can remember how much was
1690 * written. */
1691 bus->wqueue[0] = sd_bus_message_ref(m);
1692 bus->wqueue_size = 1;
1693 bus->windex = idx;
1694 }
1695 } else {
de1c301e
LP
1696 /* Just append it to the queue. */
1697
25220239 1698 if (bus->wqueue_size >= BUS_WQUEUE_MAX)
de1c301e
LP
1699 return -ENOBUFS;
1700
821e0756 1701 if (!GREEDY_REALLOC(bus->wqueue, bus->wqueue_allocated, bus->wqueue_size + 1))
de1c301e
LP
1702 return -ENOMEM;
1703
821e0756 1704 bus->wqueue[bus->wqueue_size ++] = sd_bus_message_ref(m);
de1c301e
LP
1705 }
1706
693eb9a2
LP
1707 if (cookie)
1708 *cookie = BUS_MESSAGE_COOKIE(m);
de1c301e 1709
7a37d625 1710 return 1;
de1c301e
LP
1711}
1712
069f5e61
LP
1713_public_ int sd_bus_send(sd_bus *bus, sd_bus_message *m, uint64_t *cookie) {
1714 return bus_send_internal(bus, m, cookie, false);
1715}
1716
693eb9a2 1717_public_ int sd_bus_send_to(sd_bus *bus, sd_bus_message *m, const char *destination, uint64_t *cookie) {
911121a7
LP
1718 int r;
1719
1720 assert_return(bus, -EINVAL);
1721 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
1722 assert_return(m, -EINVAL);
1723 assert_return(!bus_pid_changed(bus), -ECHILD);
1724
1725 if (!streq_ptr(m->destination, destination)) {
1726
1727 if (!destination)
1728 return -EEXIST;
1729
1730 r = sd_bus_message_set_destination(m, destination);
1731 if (r < 0)
1732 return r;
1733 }
1734
693eb9a2 1735 return sd_bus_send(bus, m, cookie);
911121a7
LP
1736}
1737
de1c301e
LP
1738static usec_t calc_elapse(uint64_t usec) {
1739 if (usec == (uint64_t) -1)
1740 return 0;
1741
de1c301e
LP
1742 return now(CLOCK_MONOTONIC) + usec;
1743}
1744
e3017af9
LP
1745static int timeout_compare(const void *a, const void *b) {
1746 const struct reply_callback *x = a, *y = b;
1747
1748 if (x->timeout != 0 && y->timeout == 0)
1749 return -1;
1750
1751 if (x->timeout == 0 && y->timeout != 0)
1752 return 1;
1753
1754 if (x->timeout < y->timeout)
1755 return -1;
1756
1757 if (x->timeout > y->timeout)
1758 return 1;
1759
1760 return 0;
1761}
1762
c49b30a2 1763_public_ int sd_bus_call_async(
de1c301e 1764 sd_bus *bus,
e1c433c6 1765 sd_bus_message *_m,
52f3ba91 1766 sd_bus_message_handler_t callback,
de1c301e
LP
1767 void *userdata,
1768 uint64_t usec,
693eb9a2 1769 uint64_t *cookie) {
de1c301e 1770
e1c433c6 1771 _cleanup_bus_message_unref_ sd_bus_message *m = sd_bus_message_ref(_m);
de1c301e
LP
1772 struct reply_callback *c;
1773 int r;
1774
d6888822
LP
1775 assert_return(bus, -EINVAL);
1776 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
1777 assert_return(m, -EINVAL);
40ca29a1 1778 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
0461f8cd 1779 assert_return(!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED), -EINVAL);
d6888822
LP
1780 assert_return(callback, -EINVAL);
1781 assert_return(!bus_pid_changed(bus), -ECHILD);
09365592 1782 assert_return(!bus->is_kernel || !(bus->hello_flags & KDBUS_HELLO_MONITOR), -EROFS);
89ffcd2a
LP
1783
1784 r = hashmap_ensure_allocated(&bus->reply_callbacks, uint64_hash_func, uint64_compare_func);
1785 if (r < 0)
1786 return r;
de1c301e 1787
3df7a7e6
LP
1788 r = prioq_ensure_allocated(&bus->reply_callbacks_prioq, timeout_compare);
1789 if (r < 0)
1790 return r;
e3017af9 1791
3df7a7e6 1792 r = bus_seal_message(bus, m, usec);
de1c301e
LP
1793 if (r < 0)
1794 return r;
1795
e1c433c6
LP
1796 r = bus_remarshal_message(bus, &m);
1797 if (r < 0)
1798 return r;
1799
eba8617e 1800 c = new0(struct reply_callback, 1);
de1c301e
LP
1801 if (!c)
1802 return -ENOMEM;
1803
1804 c->callback = callback;
1805 c->userdata = userdata;
693eb9a2 1806 c->cookie = BUS_MESSAGE_COOKIE(m);
3df7a7e6 1807 c->timeout = calc_elapse(m->timeout);
de1c301e 1808
693eb9a2 1809 r = hashmap_put(bus->reply_callbacks, &c->cookie, c);
de1c301e
LP
1810 if (r < 0) {
1811 free(c);
1812 return r;
1813 }
1814
e3017af9
LP
1815 if (c->timeout != 0) {
1816 r = prioq_put(bus->reply_callbacks_prioq, c, &c->prioq_idx);
1817 if (r < 0) {
1818 c->timeout = 0;
693eb9a2 1819 sd_bus_call_async_cancel(bus, c->cookie);
e3017af9
LP
1820 return r;
1821 }
1822 }
1823
693eb9a2 1824 r = sd_bus_send(bus, m, cookie);
de1c301e 1825 if (r < 0) {
693eb9a2 1826 sd_bus_call_async_cancel(bus, c->cookie);
de1c301e
LP
1827 return r;
1828 }
1829
1830 return r;
1831}
1832
693eb9a2 1833_public_ int sd_bus_call_async_cancel(sd_bus *bus, uint64_t cookie) {
e3017af9 1834 struct reply_callback *c;
de1c301e 1835
d6888822 1836 assert_return(bus, -EINVAL);
693eb9a2 1837 assert_return(cookie != 0, -EINVAL);
d6888822 1838 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 1839
693eb9a2 1840 c = hashmap_remove(bus->reply_callbacks, &cookie);
de1c301e
LP
1841 if (!c)
1842 return 0;
1843
e3017af9
LP
1844 if (c->timeout != 0)
1845 prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
1846
de1c301e
LP
1847 free(c);
1848 return 1;
1849}
1850
20902f3e 1851int bus_ensure_running(sd_bus *bus) {
89ffcd2a
LP
1852 int r;
1853
1854 assert(bus);
1855
718db961 1856 if (bus->state == BUS_UNSET || bus->state == BUS_CLOSED || bus->state == BUS_CLOSING)
021a1e78 1857 return -ENOTCONN;
d728d708
LP
1858 if (bus->state == BUS_RUNNING)
1859 return 1;
89ffcd2a
LP
1860
1861 for (;;) {
1862 r = sd_bus_process(bus, NULL);
1863 if (r < 0)
1864 return r;
d728d708
LP
1865 if (bus->state == BUS_RUNNING)
1866 return 1;
e3017af9
LP
1867 if (r > 0)
1868 continue;
89ffcd2a
LP
1869
1870 r = sd_bus_wait(bus, (uint64_t) -1);
1871 if (r < 0)
1872 return r;
1873 }
1874}
1875
97f82db3 1876_public_ int sd_bus_call(
de1c301e 1877 sd_bus *bus,
97f82db3 1878 sd_bus_message *_m,
de1c301e
LP
1879 uint64_t usec,
1880 sd_bus_error *error,
1881 sd_bus_message **reply) {
1882
97f82db3 1883 _cleanup_bus_message_unref_ sd_bus_message *m = sd_bus_message_ref(_m);
de1c301e 1884 usec_t timeout;
693eb9a2 1885 uint64_t cookie;
7d22c717
LP
1886 unsigned i;
1887 int r;
de1c301e 1888
97f82db3
KS
1889 assert_return(bus, -EINVAL);
1890 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
1891 assert_return(m, -EINVAL);
1892 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
1893 assert_return(!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED), -EINVAL);
1894 assert_return(!bus_error_is_dirty(error), -EINVAL);
1895 assert_return(!bus_pid_changed(bus), -ECHILD);
09365592 1896 assert_return(!bus->is_kernel || !(bus->hello_flags & KDBUS_HELLO_MONITOR), -EROFS);
97f82db3
KS
1897
1898 r = bus_ensure_running(bus);
1899 if (r < 0)
1900 return r;
1901
a43b9ca3 1902 i = bus->rqueue_size;
97f82db3
KS
1903
1904 r = bus_seal_message(bus, m, usec);
1905 if (r < 0)
1906 return r;
1907
1908 r = bus_remarshal_message(bus, &m);
1909 if (r < 0)
1910 return r;
1911
069f5e61 1912 r = bus_send_internal(bus, m, &cookie, true);
de1c301e
LP
1913 if (r < 0)
1914 return r;
1915
3df7a7e6 1916 timeout = calc_elapse(m->timeout);
de1c301e
LP
1917
1918 for (;;) {
1919 usec_t left;
de1c301e 1920
7d22c717
LP
1921 while (i < bus->rqueue_size) {
1922 sd_bus_message *incoming = NULL;
1923
1924 incoming = bus->rqueue[i];
89ffcd2a 1925
693eb9a2 1926 if (incoming->reply_cookie == cookie) {
de1c301e
LP
1927 /* Found a match! */
1928
7d22c717
LP
1929 memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1));
1930 bus->rqueue_size--;
1931
40ca29a1 1932 if (incoming->header->type == SD_BUS_MESSAGE_METHOD_RETURN) {
b7f247e0 1933
2ce97e2b
LP
1934 if (incoming->n_fds <= 0 || (bus->hello_flags & KDBUS_HELLO_ACCEPT_FD)) {
1935 if (reply)
1936 *reply = incoming;
1937 else
1938 sd_bus_message_unref(incoming);
1939
1940 return 1;
1941 }
1942
1943 r = sd_bus_error_setf(error, SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Reply message contained file descriptors which I couldn't accept. Sorry.");
b7f247e0 1944
a43b9ca3 1945 } else if (incoming->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
de1c301e 1946 r = sd_bus_error_copy(error, &incoming->error);
a43b9ca3
LP
1947 else
1948 r = -EIO;
de1c301e
LP
1949
1950 sd_bus_message_unref(incoming);
a43b9ca3 1951 return r;
a8a07f89 1952
693eb9a2 1953 } else if (BUS_MESSAGE_COOKIE(incoming) == cookie &&
a8a07f89
LP
1954 bus->unique_name &&
1955 incoming->sender &&
1956 streq(bus->unique_name, incoming->sender)) {
1957
7d22c717
LP
1958 memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1));
1959 bus->rqueue_size--;
1960
a8a07f89
LP
1961 /* Our own message? Somebody is trying
1962 * to send its own client a message,
1963 * let's not dead-lock, let's fail
1964 * immediately. */
1965
1966 sd_bus_message_unref(incoming);
1967 return -ELOOP;
de1c301e
LP
1968 }
1969
de1c301e 1970 /* Try to read more, right-away */
7d22c717 1971 i++;
de1c301e 1972 }
7d22c717 1973
766c5809 1974 r = bus_read_message(bus, false, 0);
32f46480 1975 if (r < 0) {
441d56a1 1976 if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
32f46480 1977 bus_enter_closing(bus);
441d56a1
LP
1978 return -ECONNRESET;
1979 }
32f46480 1980
a43b9ca3 1981 return r;
32f46480 1982 }
7d22c717 1983 if (r > 0)
e3017af9 1984 continue;
de1c301e
LP
1985
1986 if (timeout > 0) {
1987 usec_t n;
1988
1989 n = now(CLOCK_MONOTONIC);
1990 if (n >= timeout)
1991 return -ETIMEDOUT;
1992
1993 left = timeout - n;
1994 } else
1995 left = (uint64_t) -1;
1996
e3017af9 1997 r = bus_poll(bus, true, left);
de1c301e
LP
1998 if (r < 0)
1999 return r;
f8e11cda
LP
2000 if (r == 0)
2001 return -ETIMEDOUT;
de1c301e
LP
2002
2003 r = dispatch_wqueue(bus);
32f46480 2004 if (r < 0) {
441d56a1 2005 if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
32f46480 2006 bus_enter_closing(bus);
441d56a1
LP
2007 return -ECONNRESET;
2008 }
32f46480 2009
de1c301e 2010 return r;
32f46480 2011 }
de1c301e
LP
2012 }
2013}
2014
d9f644e2 2015_public_ int sd_bus_get_fd(sd_bus *bus) {
d6888822
LP
2016
2017 assert_return(bus, -EINVAL);
d6888822
LP
2018 assert_return(bus->input_fd == bus->output_fd, -EPERM);
2019 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 2020
e82c9509 2021 return bus->input_fd;
de1c301e
LP
2022}
2023
d9f644e2 2024_public_ int sd_bus_get_events(sd_bus *bus) {
de1c301e
LP
2025 int flags = 0;
2026
d6888822 2027 assert_return(bus, -EINVAL);
718db961 2028 assert_return(BUS_IS_OPEN(bus->state) || bus->state == BUS_CLOSING, -ENOTCONN);
d6888822 2029 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e
LP
2030
2031 if (bus->state == BUS_OPENING)
2032 flags |= POLLOUT;
89ffcd2a
LP
2033 else if (bus->state == BUS_AUTHENTICATING) {
2034
2181a7f5 2035 if (bus_socket_auth_needs_write(bus))
89ffcd2a
LP
2036 flags |= POLLOUT;
2037
2038 flags |= POLLIN;
2039
2040 } else if (bus->state == BUS_RUNNING || bus->state == BUS_HELLO) {
de1c301e
LP
2041 if (bus->rqueue_size <= 0)
2042 flags |= POLLIN;
2043 if (bus->wqueue_size > 0)
2044 flags |= POLLOUT;
2045 }
2046
2047 return flags;
2048}
2049
d9f644e2 2050_public_ int sd_bus_get_timeout(sd_bus *bus, uint64_t *timeout_usec) {
e3017af9
LP
2051 struct reply_callback *c;
2052
d6888822
LP
2053 assert_return(bus, -EINVAL);
2054 assert_return(timeout_usec, -EINVAL);
718db961 2055 assert_return(BUS_IS_OPEN(bus->state) || bus->state == BUS_CLOSING, -ENOTCONN);
d6888822 2056 assert_return(!bus_pid_changed(bus), -ECHILD);
e3017af9 2057
8f8f05a9
LP
2058 if (bus->track_queue) {
2059 *timeout_usec = 0;
2060 return 1;
2061 }
2062
718db961
LP
2063 if (bus->state == BUS_CLOSING) {
2064 *timeout_usec = 0;
2065 return 1;
2066 }
2067
e3017af9
LP
2068 if (bus->state == BUS_AUTHENTICATING) {
2069 *timeout_usec = bus->auth_timeout;
2070 return 1;
2071 }
2072
adee69fa
LP
2073 if (bus->state != BUS_RUNNING && bus->state != BUS_HELLO) {
2074 *timeout_usec = (uint64_t) -1;
e3017af9 2075 return 0;
adee69fa 2076 }
e3017af9 2077
8efd6381
LP
2078 if (bus->rqueue_size > 0) {
2079 *timeout_usec = 0;
2080 return 1;
2081 }
2082
e3017af9 2083 c = prioq_peek(bus->reply_callbacks_prioq);
adee69fa
LP
2084 if (!c) {
2085 *timeout_usec = (uint64_t) -1;
e3017af9 2086 return 0;
adee69fa 2087 }
e3017af9
LP
2088
2089 *timeout_usec = c->timeout;
2090 return 1;
2091}
2092
2093static int process_timeout(sd_bus *bus) {
ebcf1f97 2094 _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
eb01ba5d 2095 _cleanup_bus_message_unref_ sd_bus_message* m = NULL;
e3017af9
LP
2096 struct reply_callback *c;
2097 usec_t n;
2098 int r;
2099
2100 assert(bus);
2101
2102 c = prioq_peek(bus->reply_callbacks_prioq);
2103 if (!c)
2104 return 0;
2105
2106 n = now(CLOCK_MONOTONIC);
2107 if (c->timeout > n)
2108 return 0;
2109
eb01ba5d
LP
2110 r = bus_message_new_synthetic_error(
2111 bus,
693eb9a2 2112 c->cookie,
14c24659 2113 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out"),
eb01ba5d
LP
2114 &m);
2115 if (r < 0)
2116 return r;
2117
34a2c9e8
LP
2118 m->sender = "org.freedesktop.DBus";
2119
7adc46fc 2120 r = bus_seal_synthetic_message(bus, m);
718db961
LP
2121 if (r < 0)
2122 return r;
2123
e3017af9 2124 assert_se(prioq_pop(bus->reply_callbacks_prioq) == c);
693eb9a2 2125 hashmap_remove(bus->reply_callbacks, &c->cookie);
e3017af9 2126
718db961
LP
2127 bus->current = m;
2128 bus->iteration_counter ++;
2129
ebcf1f97
LP
2130 r = c->callback(bus, m, c->userdata, &error_buffer);
2131 r = bus_maybe_reply_error(m, r, &error_buffer);
e3017af9
LP
2132 free(c);
2133
718db961
LP
2134 bus->current = NULL;
2135
ebcf1f97 2136 return r;
e3017af9
LP
2137}
2138
9d373862
LP
2139static int process_hello(sd_bus *bus, sd_bus_message *m) {
2140 assert(bus);
2141 assert(m);
2142
2143 if (bus->state != BUS_HELLO)
2144 return 0;
2145
2146 /* Let's make sure the first message on the bus is the HELLO
2147 * reply. But note that we don't actually parse the message
2181a7f5
LP
2148 * here (we leave that to the usual handling), we just verify
2149 * we don't let any earlier msg through. */
9d373862 2150
40ca29a1
LP
2151 if (m->header->type != SD_BUS_MESSAGE_METHOD_RETURN &&
2152 m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
9d373862
LP
2153 return -EIO;
2154
693eb9a2 2155 if (m->reply_cookie != bus->hello_cookie)
9d373862
LP
2156 return -EIO;
2157
2158 return 0;
2159}
2160
a652755d 2161static int process_reply(sd_bus *bus, sd_bus_message *m) {
2ce97e2b 2162 _cleanup_bus_message_unref_ sd_bus_message *synthetic_reply = NULL;
ebcf1f97 2163 _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
2ce97e2b 2164 _cleanup_free_ struct reply_callback *c = NULL;
a652755d
LP
2165 int r;
2166
2167 assert(bus);
2168 assert(m);
2169
40ca29a1
LP
2170 if (m->header->type != SD_BUS_MESSAGE_METHOD_RETURN &&
2171 m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
a652755d
LP
2172 return 0;
2173
09365592
LP
2174 if (bus->is_kernel && (bus->hello_flags & KDBUS_HELLO_MONITOR))
2175 return 0;
2176
2177 if (m->destination && bus->unique_name && !streq_ptr(m->destination, bus->unique_name))
2178 return 0;
2179
693eb9a2 2180 c = hashmap_remove(bus->reply_callbacks, &m->reply_cookie);
a652755d
LP
2181 if (!c)
2182 return 0;
2183
2184 if (c->timeout != 0)
2185 prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
2186
2ce97e2b
LP
2187 if (m->n_fds > 0 && !(bus->hello_flags & KDBUS_HELLO_ACCEPT_FD)) {
2188
2189 /* If the reply contained a file descriptor which we
2190 * didn't want we pass an error instead. */
2191
2192 r = bus_message_new_synthetic_error(
2193 bus,
2194 m->reply_cookie,
2195 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Reply message contained file descriptor"),
2196 &synthetic_reply);
2197 if (r < 0)
2198 return r;
2199
2200 r = bus_seal_synthetic_message(bus, synthetic_reply);
2201 if (r < 0)
2202 return r;
2203
2204 m = synthetic_reply;
2205 } else {
2206 r = sd_bus_message_rewind(m, true);
2207 if (r < 0)
2208 return r;
2209 }
88fe224c 2210
ebcf1f97
LP
2211 r = c->callback(bus, m, c->userdata, &error_buffer);
2212 r = bus_maybe_reply_error(m, r, &error_buffer);
a652755d 2213
ebcf1f97 2214 return r;
a652755d
LP
2215}
2216
2217static int process_filter(sd_bus *bus, sd_bus_message *m) {
ebcf1f97 2218 _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
a652755d
LP
2219 struct filter_callback *l;
2220 int r;
2221
392d5b37
LP
2222 assert(bus);
2223 assert(m);
2224
7286037f
LP
2225 do {
2226 bus->filter_callbacks_modified = false;
2227
2228 LIST_FOREACH(callbacks, l, bus->filter_callbacks) {
2229
2230 if (bus->filter_callbacks_modified)
2231 break;
2232
2233 /* Don't run this more than once per iteration */
2234 if (l->last_iteration == bus->iteration_counter)
2235 continue;
2236
2237 l->last_iteration = bus->iteration_counter;
2238
88fe224c
LP
2239 r = sd_bus_message_rewind(m, true);
2240 if (r < 0)
2241 return r;
2242
969987ea 2243 r = l->callback(bus, m, l->userdata, &error_buffer);
ebcf1f97 2244 r = bus_maybe_reply_error(m, r, &error_buffer);
7286037f
LP
2245 if (r != 0)
2246 return r;
2247
2248 }
2249
2250 } while (bus->filter_callbacks_modified);
a652755d
LP
2251
2252 return 0;
2253}
2254
392d5b37 2255static int process_match(sd_bus *bus, sd_bus_message *m) {
7286037f
LP
2256 int r;
2257
392d5b37
LP
2258 assert(bus);
2259 assert(m);
2260
7286037f
LP
2261 do {
2262 bus->match_callbacks_modified = false;
2263
eb01ba5d 2264 r = bus_match_run(bus, &bus->match_callbacks, m);
7286037f
LP
2265 if (r != 0)
2266 return r;
2267
2268 } while (bus->match_callbacks_modified);
2269
2270 return 0;
392d5b37
LP
2271}
2272
b9bf7e2b
LP
2273static int process_builtin(sd_bus *bus, sd_bus_message *m) {
2274 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2275 int r;
2276
2277 assert(bus);
2278 assert(m);
2279
09365592
LP
2280 if (bus->hello_flags & KDBUS_HELLO_MONITOR)
2281 return 0;
2282
758bf0c7
LP
2283 if (bus->manual_peer_interface)
2284 return 0;
2285
40ca29a1 2286 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
b9bf7e2b
LP
2287 return 0;
2288
2289 if (!streq_ptr(m->interface, "org.freedesktop.DBus.Peer"))
2290 return 0;
2291
0461f8cd 2292 if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
b9bf7e2b
LP
2293 return 1;
2294
2295 if (streq_ptr(m->member, "Ping"))
df2d202e 2296 r = sd_bus_message_new_method_return(m, &reply);
b9bf7e2b
LP
2297 else if (streq_ptr(m->member, "GetMachineId")) {
2298 sd_id128_t id;
2299 char sid[33];
2300
2301 r = sd_id128_get_machine(&id);
2302 if (r < 0)
2303 return r;
2304
df2d202e 2305 r = sd_bus_message_new_method_return(m, &reply);
b9bf7e2b
LP
2306 if (r < 0)
2307 return r;
2308
2309 r = sd_bus_message_append(reply, "s", sd_id128_to_string(id, sid));
2310 } else {
29ddb38f 2311 r = sd_bus_message_new_method_errorf(
df2d202e 2312 m, &reply,
40ca29a1 2313 SD_BUS_ERROR_UNKNOWN_METHOD,
b9bf7e2b 2314 "Unknown method '%s' on interface '%s'.", m->member, m->interface);
b9bf7e2b
LP
2315 }
2316
2317 if (r < 0)
2318 return r;
2319
2320 r = sd_bus_send(bus, reply, NULL);
2321 if (r < 0)
2322 return r;
2323
2324 return 1;
2325}
2326
2ce97e2b
LP
2327static int process_fd_check(sd_bus *bus, sd_bus_message *m) {
2328 assert(bus);
2329 assert(m);
2330
2331 /* If we got a message with a file descriptor which we didn't
2332 * want to accept, then let's drop it. How can this even
2333 * happen? For example, when the kernel queues a message into
2334 * an activatable names's queue which allows fds, and then is
2335 * delivered to us later even though we ourselves did not
2336 * negotiate it. */
2337
09365592
LP
2338 if (bus->hello_flags & KDBUS_HELLO_MONITOR)
2339 return 0;
2340
2ce97e2b
LP
2341 if (m->n_fds <= 0)
2342 return 0;
2343
2344 if (bus->hello_flags & KDBUS_HELLO_ACCEPT_FD)
2345 return 0;
2346
2347 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
2348 return 1; /* just eat it up */
2349
2350 return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Message contains file descriptors, which I cannot accept. Sorry.");
2351}
2352
992c052c 2353static int process_message(sd_bus *bus, sd_bus_message *m) {
e3017af9
LP
2354 int r;
2355
2356 assert(bus);
992c052c 2357 assert(m);
e3017af9 2358
affff0b6 2359 bus->current = m;
992c052c 2360 bus->iteration_counter++;
e3017af9 2361
42c4ebcb 2362 log_debug("Got message type=%s sender=%s destination=%s object=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " error=%s",
4cdf0751 2363 bus_message_type_to_string(m->header->type),
40ca29a1 2364 strna(sd_bus_message_get_sender(m)),
4cdf0751 2365 strna(sd_bus_message_get_destination(m)),
40ca29a1
LP
2366 strna(sd_bus_message_get_path(m)),
2367 strna(sd_bus_message_get_interface(m)),
4cdf0751 2368 strna(sd_bus_message_get_member(m)),
42c4ebcb
LP
2369 BUS_MESSAGE_COOKIE(m),
2370 m->reply_cookie,
4cdf0751 2371 strna(m->error.message));
40ca29a1 2372
992c052c
LP
2373 r = process_hello(bus, m);
2374 if (r != 0)
affff0b6 2375 goto finish;
a652755d 2376
992c052c
LP
2377 r = process_reply(bus, m);
2378 if (r != 0)
affff0b6 2379 goto finish;
e3017af9 2380
2ce97e2b
LP
2381 r = process_fd_check(bus, m);
2382 if (r != 0)
2383 goto finish;
2384
992c052c
LP
2385 r = process_filter(bus, m);
2386 if (r != 0)
affff0b6 2387 goto finish;
a652755d 2388
992c052c
LP
2389 r = process_match(bus, m);
2390 if (r != 0)
affff0b6 2391 goto finish;
a652755d 2392
992c052c
LP
2393 r = process_builtin(bus, m);
2394 if (r != 0)
affff0b6
LP
2395 goto finish;
2396
2397 r = bus_process_object(bus, m);
a652755d 2398
affff0b6
LP
2399finish:
2400 bus->current = NULL;
2401 return r;
29ddb38f 2402}
88fe224c 2403
8f8f05a9
LP
2404static int dispatch_track(sd_bus *bus) {
2405 assert(bus);
2406
2407 if (!bus->track_queue)
2408 return 0;
2409
2410 bus_track_dispatch(bus->track_queue);
2411 return 1;
2412}
2413
766c5809 2414static int process_running(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **ret) {
992c052c 2415 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
29ddb38f 2416 int r;
a652755d 2417
29ddb38f 2418 assert(bus);
992c052c 2419 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
7286037f 2420
992c052c
LP
2421 r = process_timeout(bus);
2422 if (r != 0)
2423 goto null_message;
7286037f 2424
992c052c
LP
2425 r = dispatch_wqueue(bus);
2426 if (r != 0)
2427 goto null_message;
7286037f 2428
8f8f05a9
LP
2429 r = dispatch_track(bus);
2430 if (r != 0)
2431 goto null_message;
2432
766c5809 2433 r = dispatch_rqueue(bus, hint_priority, priority, &m);
992c052c
LP
2434 if (r < 0)
2435 return r;
2436 if (!m)
2437 goto null_message;
7286037f 2438
992c052c
LP
2439 r = process_message(bus, m);
2440 if (r != 0)
2441 goto null_message;
7286037f 2442
992c052c
LP
2443 if (ret) {
2444 r = sd_bus_message_rewind(m, true);
29ddb38f
LP
2445 if (r < 0)
2446 return r;
e3017af9 2447
992c052c
LP
2448 *ret = m;
2449 m = NULL;
2450 return 1;
2451 }
a652755d 2452
40ca29a1 2453 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL) {
a652755d 2454
dc74ce9b
LP
2455 log_debug("Unprocessed message call sender=%s object=%s interface=%s member=%s",
2456 strna(sd_bus_message_get_sender(m)),
2457 strna(sd_bus_message_get_path(m)),
2458 strna(sd_bus_message_get_interface(m)),
2459 strna(sd_bus_message_get_member(m)));
2460
992c052c 2461 r = sd_bus_reply_method_errorf(
df2d202e 2462 m,
40ca29a1 2463 SD_BUS_ERROR_UNKNOWN_OBJECT,
992c052c 2464 "Unknown object '%s'.", m->path);
29ddb38f
LP
2465 if (r < 0)
2466 return r;
2467 }
e3017af9 2468
992c052c 2469 return 1;
0a72c2bd 2470
992c052c
LP
2471null_message:
2472 if (r >= 0 && ret)
2473 *ret = NULL;
0a72c2bd 2474
992c052c 2475 return r;
29ddb38f 2476}
0a72c2bd 2477
718db961
LP
2478static int process_closing(sd_bus *bus, sd_bus_message **ret) {
2479 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2480 struct reply_callback *c;
2481 int r;
2482
2483 assert(bus);
2484 assert(bus->state == BUS_CLOSING);
2485
2486 c = hashmap_first(bus->reply_callbacks);
2487 if (c) {
ebcf1f97
LP
2488 _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
2489
718db961
LP
2490 /* First, fail all outstanding method calls */
2491 r = bus_message_new_synthetic_error(
2492 bus,
693eb9a2 2493 c->cookie,
14c24659 2494 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Connection terminated"),
718db961
LP
2495 &m);
2496 if (r < 0)
2497 return r;
2498
7adc46fc 2499 r = bus_seal_synthetic_message(bus, m);
718db961
LP
2500 if (r < 0)
2501 return r;
2502
2503 if (c->timeout != 0)
2504 prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
2505
693eb9a2 2506 hashmap_remove(bus->reply_callbacks, &c->cookie);
718db961
LP
2507
2508 bus->current = m;
2509 bus->iteration_counter++;
2510
ebcf1f97
LP
2511 r = c->callback(bus, m, c->userdata, &error_buffer);
2512 r = bus_maybe_reply_error(m, r, &error_buffer);
718db961
LP
2513 free(c);
2514
718db961
LP
2515 goto finish;
2516 }
2517
2518 /* Then, synthesize a Disconnected message */
2519 r = sd_bus_message_new_signal(
2520 bus,
151b9b96 2521 &m,
718db961
LP
2522 "/org/freedesktop/DBus/Local",
2523 "org.freedesktop.DBus.Local",
151b9b96 2524 "Disconnected");
718db961
LP
2525 if (r < 0)
2526 return r;
2527
34a2c9e8
LP
2528 m->sender = "org.freedesktop.DBus.Local";
2529
7adc46fc 2530 r = bus_seal_synthetic_message(bus, m);
718db961
LP
2531 if (r < 0)
2532 return r;
2533
2534 sd_bus_close(bus);
2535
2536 bus->current = m;
2537 bus->iteration_counter++;
2538
2539 r = process_filter(bus, m);
2540 if (r != 0)
2541 goto finish;
2542
2543 r = process_match(bus, m);
2544 if (r != 0)
2545 goto finish;
2546
2547 if (ret) {
2548 *ret = m;
2549 m = NULL;
2550 }
2551
2552 r = 1;
2553
2554finish:
2555 bus->current = NULL;
2556 return r;
2557}
2558
766c5809 2559static int bus_process_internal(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **ret) {
8ce2afd6 2560 BUS_DONT_DESTROY(bus);
29ddb38f 2561 int r;
0a72c2bd 2562
992c052c
LP
2563 /* Returns 0 when we didn't do anything. This should cause the
2564 * caller to invoke sd_bus_wait() before returning the next
2565 * time. Returns > 0 when we did something, which possibly
2566 * means *ret is filled in with an unprocessed message. */
0a72c2bd 2567
d6888822
LP
2568 assert_return(bus, -EINVAL);
2569 assert_return(!bus_pid_changed(bus), -ECHILD);
0a72c2bd 2570
992c052c 2571 /* We don't allow recursively invoking sd_bus_process(). */
718db961 2572 assert_return(!bus->current, -EBUSY);
0a72c2bd 2573
992c052c 2574 switch (bus->state) {
0a72c2bd 2575
992c052c 2576 case BUS_UNSET:
992c052c 2577 return -ENOTCONN;
0a72c2bd 2578
6d6f4904
LP
2579 case BUS_CLOSED:
2580 return -ECONNRESET;
2581
992c052c
LP
2582 case BUS_OPENING:
2583 r = bus_socket_process_opening(bus);
441d56a1 2584 if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
718db961
LP
2585 bus_enter_closing(bus);
2586 r = 1;
2587 } else if (r < 0)
29ddb38f 2588 return r;
992c052c
LP
2589 if (ret)
2590 *ret = NULL;
a652755d
LP
2591 return r;
2592
992c052c 2593 case BUS_AUTHENTICATING:
992c052c 2594 r = bus_socket_process_authenticating(bus);
441d56a1 2595 if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
718db961
LP
2596 bus_enter_closing(bus);
2597 r = 1;
2598 } else if (r < 0)
29ddb38f 2599 return r;
718db961 2600
992c052c
LP
2601 if (ret)
2602 *ret = NULL;
718db961 2603
992c052c 2604 return r;
a652755d 2605
992c052c
LP
2606 case BUS_RUNNING:
2607 case BUS_HELLO:
766c5809 2608 r = process_running(bus, hint_priority, priority, ret);
441d56a1 2609 if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
718db961
LP
2610 bus_enter_closing(bus);
2611 r = 1;
2612
2613 if (ret)
2614 *ret = NULL;
2615 }
43a43f50 2616
43a43f50 2617 return r;
718db961
LP
2618
2619 case BUS_CLOSING:
2620 return process_closing(bus, ret);
992c052c 2621 }
43a43f50 2622
992c052c 2623 assert_not_reached("Unknown state");
e3017af9
LP
2624}
2625
766c5809
LP
2626_public_ int sd_bus_process(sd_bus *bus, sd_bus_message **ret) {
2627 return bus_process_internal(bus, false, 0, ret);
2628}
2629
2630_public_ int sd_bus_process_priority(sd_bus *bus, int64_t priority, sd_bus_message **ret) {
2631 return bus_process_internal(bus, true, priority, ret);
2632}
2633
992c052c
LP
2634static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec) {
2635 struct pollfd p[2] = {};
2636 int r, e, n;
2637 struct timespec ts;
8efd6381 2638 usec_t m = (usec_t) -1;
adcdb374
LP
2639
2640 assert(bus);
718db961
LP
2641
2642 if (bus->state == BUS_CLOSING)
2643 return 1;
2644
d6888822 2645 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
adcdb374 2646
992c052c
LP
2647 e = sd_bus_get_events(bus);
2648 if (e < 0)
2649 return e;
adcdb374 2650
992c052c 2651 if (need_more)
8efd6381
LP
2652 /* The caller really needs some more data, he doesn't
2653 * care about what's already read, or any timeouts
2654 * except its own.*/
992c052c 2655 e |= POLLIN;
992c052c 2656 else {
8efd6381
LP
2657 usec_t until;
2658 /* The caller wants to process if there's something to
2659 * process, but doesn't care otherwise */
2660
2661 r = sd_bus_get_timeout(bus, &until);
2662 if (r < 0)
2663 return r;
2664 if (r > 0) {
2665 usec_t nw;
2666 nw = now(CLOCK_MONOTONIC);
2667 m = until > nw ? until - nw : 0;
2668 }
992c052c 2669 }
adcdb374 2670
992c052c
LP
2671 if (timeout_usec != (uint64_t) -1 && (m == (uint64_t) -1 || timeout_usec < m))
2672 m = timeout_usec;
adcdb374 2673
992c052c
LP
2674 p[0].fd = bus->input_fd;
2675 if (bus->output_fd == bus->input_fd) {
2676 p[0].events = e;
2677 n = 1;
2678 } else {
2679 p[0].events = e & POLLIN;
2680 p[1].fd = bus->output_fd;
2681 p[1].events = e & POLLOUT;
2682 n = 2;
adcdb374
LP
2683 }
2684
992c052c 2685 r = ppoll(p, n, m == (uint64_t) -1 ? NULL : timespec_store(&ts, m), NULL);
adcdb374 2686 if (r < 0)
992c052c 2687 return -errno;
adcdb374 2688
992c052c 2689 return r > 0 ? 1 : 0;
adcdb374
LP
2690}
2691
d9f644e2 2692_public_ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) {
9db76355 2693
d6888822 2694 assert_return(bus, -EINVAL);
d6888822 2695 assert_return(!bus_pid_changed(bus), -ECHILD);
9db76355 2696
718db961
LP
2697 if (bus->state == BUS_CLOSING)
2698 return 0;
2699
2700 assert_return(BUS_IS_OPEN(bus->state) , -ENOTCONN);
2701
992c052c
LP
2702 if (bus->rqueue_size > 0)
2703 return 0;
9db76355 2704
992c052c
LP
2705 return bus_poll(bus, false, timeout_usec);
2706}
9db76355 2707
d9f644e2 2708_public_ int sd_bus_flush(sd_bus *bus) {
992c052c 2709 int r;
9db76355 2710
d6888822 2711 assert_return(bus, -EINVAL);
d6888822 2712 assert_return(!bus_pid_changed(bus), -ECHILD);
9db76355 2713
718db961
LP
2714 if (bus->state == BUS_CLOSING)
2715 return 0;
2716
2717 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
2718
992c052c
LP
2719 r = bus_ensure_running(bus);
2720 if (r < 0)
2721 return r;
9db76355 2722
992c052c
LP
2723 if (bus->wqueue_size <= 0)
2724 return 0;
9db76355 2725
992c052c
LP
2726 for (;;) {
2727 r = dispatch_wqueue(bus);
32f46480 2728 if (r < 0) {
441d56a1 2729 if (r == -ENOTCONN || r == -ECONNRESET || r == -EPIPE || r == -ESHUTDOWN) {
32f46480 2730 bus_enter_closing(bus);
441d56a1
LP
2731 return -ECONNRESET;
2732 }
32f46480 2733
9db76355 2734 return r;
32f46480 2735 }
9db76355 2736
992c052c
LP
2737 if (bus->wqueue_size <= 0)
2738 return 0;
9db76355 2739
992c052c 2740 r = bus_poll(bus, false, (uint64_t) -1);
9db76355
LP
2741 if (r < 0)
2742 return r;
9db76355 2743 }
9db76355
LP
2744}
2745
d9f644e2
ZJS
2746_public_ int sd_bus_add_filter(sd_bus *bus,
2747 sd_bus_message_handler_t callback,
2748 void *userdata) {
2749
992c052c 2750 struct filter_callback *f;
de1c301e 2751
d6888822
LP
2752 assert_return(bus, -EINVAL);
2753 assert_return(callback, -EINVAL);
2754 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 2755
992c052c
LP
2756 f = new0(struct filter_callback, 1);
2757 if (!f)
29ddb38f 2758 return -ENOMEM;
992c052c
LP
2759 f->callback = callback;
2760 f->userdata = userdata;
29ddb38f 2761
992c052c 2762 bus->filter_callbacks_modified = true;
71fda00f 2763 LIST_PREPEND(callbacks, bus->filter_callbacks, f);
de1c301e
LP
2764 return 0;
2765}
a652755d 2766
d9f644e2
ZJS
2767_public_ int sd_bus_remove_filter(sd_bus *bus,
2768 sd_bus_message_handler_t callback,
2769 void *userdata) {
2770
992c052c 2771 struct filter_callback *f;
a652755d 2772
d6888822
LP
2773 assert_return(bus, -EINVAL);
2774 assert_return(callback, -EINVAL);
2775 assert_return(!bus_pid_changed(bus), -ECHILD);
a652755d 2776
992c052c
LP
2777 LIST_FOREACH(callbacks, f, bus->filter_callbacks) {
2778 if (f->callback == callback && f->userdata == userdata) {
2779 bus->filter_callbacks_modified = true;
71fda00f 2780 LIST_REMOVE(callbacks, bus->filter_callbacks, f);
992c052c
LP
2781 free(f);
2782 return 1;
29ddb38f
LP
2783 }
2784 }
2785
992c052c 2786 return 0;
a652755d 2787}
392d5b37 2788
d9f644e2
ZJS
2789_public_ int sd_bus_add_match(sd_bus *bus,
2790 const char *match,
2791 sd_bus_message_handler_t callback,
2792 void *userdata) {
2793
992c052c
LP
2794 struct bus_match_component *components = NULL;
2795 unsigned n_components = 0;
2796 uint64_t cookie = 0;
2797 int r = 0;
392d5b37 2798
d6888822
LP
2799 assert_return(bus, -EINVAL);
2800 assert_return(match, -EINVAL);
2801 assert_return(!bus_pid_changed(bus), -ECHILD);
392d5b37 2802
992c052c
LP
2803 r = bus_match_parse(match, &components, &n_components);
2804 if (r < 0)
2805 goto finish;
29ddb38f 2806
992c052c
LP
2807 if (bus->bus_client) {
2808 cookie = ++bus->match_cookie;
29ddb38f 2809
992c052c
LP
2810 r = bus_add_match_internal(bus, match, components, n_components, cookie);
2811 if (r < 0)
2812 goto finish;
392d5b37
LP
2813 }
2814
992c052c
LP
2815 bus->match_callbacks_modified = true;
2816 r = bus_match_add(&bus->match_callbacks, components, n_components, callback, userdata, cookie, NULL);
29ddb38f 2817 if (r < 0) {
992c052c
LP
2818 if (bus->bus_client)
2819 bus_remove_match_internal(bus, match, cookie);
29ddb38f 2820 }
917b5dc7 2821
992c052c
LP
2822finish:
2823 bus_match_parse_free(components, n_components);
2824 return r;
917b5dc7
LP
2825}
2826
d9f644e2
ZJS
2827_public_ int sd_bus_remove_match(sd_bus *bus,
2828 const char *match,
2829 sd_bus_message_handler_t callback,
2830 void *userdata) {
2831
992c052c
LP
2832 struct bus_match_component *components = NULL;
2833 unsigned n_components = 0;
2834 int r = 0, q = 0;
2835 uint64_t cookie = 0;
917b5dc7 2836
d6888822
LP
2837 assert_return(bus, -EINVAL);
2838 assert_return(match, -EINVAL);
2839 assert_return(!bus_pid_changed(bus), -ECHILD);
917b5dc7 2840
992c052c 2841 r = bus_match_parse(match, &components, &n_components);
29ddb38f
LP
2842 if (r < 0)
2843 return r;
f10dda3b 2844
992c052c
LP
2845 bus->match_callbacks_modified = true;
2846 r = bus_match_remove(&bus->match_callbacks, components, n_components, callback, userdata, &cookie);
f10dda3b 2847
992c052c
LP
2848 if (bus->bus_client)
2849 q = bus_remove_match_internal(bus, match, cookie);
f10dda3b 2850
992c052c 2851 bus_match_parse_free(components, n_components);
f10dda3b 2852
992c052c 2853 return r < 0 ? r : q;
f10dda3b
LP
2854}
2855
992c052c
LP
2856bool bus_pid_changed(sd_bus *bus) {
2857 assert(bus);
f10dda3b 2858
992c052c
LP
2859 /* We don't support people creating a bus connection and
2860 * keeping it around over a fork(). Let's complain. */
d5a2b9a6 2861
992c052c 2862 return bus->original_pid != getpid();
d5a2b9a6 2863}
40ca29a1
LP
2864
2865static int io_callback(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
0927756b 2866 sd_bus *bus = userdata;
40ca29a1
LP
2867 int r;
2868
2869 assert(bus);
2870
2871 r = sd_bus_process(bus, NULL);
2872 if (r < 0)
2873 return r;
2874
2875 return 1;
2876}
2877
2878static int time_callback(sd_event_source *s, uint64_t usec, void *userdata) {
0927756b 2879 sd_bus *bus = userdata;
40ca29a1
LP
2880 int r;
2881
2882 assert(bus);
2883
2884 r = sd_bus_process(bus, NULL);
2885 if (r < 0)
2886 return r;
2887
2888 return 1;
2889}
2890
2891static int prepare_callback(sd_event_source *s, void *userdata) {
2892 sd_bus *bus = userdata;
2893 int r, e;
2894 usec_t until;
2895
2896 assert(s);
2897 assert(bus);
2898
2899 e = sd_bus_get_events(bus);
2900 if (e < 0)
2901 return e;
2902
2903 if (bus->output_fd != bus->input_fd) {
2904
2905 r = sd_event_source_set_io_events(bus->input_io_event_source, e & POLLIN);
2906 if (r < 0)
2907 return r;
2908
2909 r = sd_event_source_set_io_events(bus->output_io_event_source, e & POLLOUT);
2910 if (r < 0)
2911 return r;
2912 } else {
2913 r = sd_event_source_set_io_events(bus->input_io_event_source, e);
2914 if (r < 0)
2915 return r;
2916 }
2917
2918 r = sd_bus_get_timeout(bus, &until);
2919 if (r < 0)
2920 return r;
2921 if (r > 0) {
2922 int j;
2923
2924 j = sd_event_source_set_time(bus->time_event_source, until);
2925 if (j < 0)
2926 return j;
2927 }
2928
2929 r = sd_event_source_set_enabled(bus->time_event_source, r > 0);
2930 if (r < 0)
2931 return r;
2932
2933 return 1;
2934}
2935
abc5fe72
LP
2936static int quit_callback(sd_event_source *event, void *userdata) {
2937 sd_bus *bus = userdata;
2938
2939 assert(event);
2940
2941 sd_bus_flush(bus);
2942
2943 return 1;
2944}
2945
1e05d493
LP
2946static int attach_io_events(sd_bus *bus) {
2947 int r;
2948
2949 assert(bus);
2950
2951 if (bus->input_fd < 0)
2952 return 0;
2953
2954 if (!bus->event)
2955 return 0;
2956
2957 if (!bus->input_io_event_source) {
151b9b96 2958 r = sd_event_add_io(bus->event, &bus->input_io_event_source, bus->input_fd, 0, io_callback, bus);
1e05d493
LP
2959 if (r < 0)
2960 return r;
2961
2962 r = sd_event_source_set_prepare(bus->input_io_event_source, prepare_callback);
2963 if (r < 0)
2964 return r;
2965
2966 r = sd_event_source_set_priority(bus->input_io_event_source, bus->event_priority);
2967 } else
2968 r = sd_event_source_set_io_fd(bus->input_io_event_source, bus->input_fd);
2969
2970 if (r < 0)
2971 return r;
2972
2973 if (bus->output_fd != bus->input_fd) {
2974 assert(bus->output_fd >= 0);
2975
2976 if (!bus->output_io_event_source) {
151b9b96 2977 r = sd_event_add_io(bus->event, &bus->output_io_event_source, bus->output_fd, 0, io_callback, bus);
1e05d493
LP
2978 if (r < 0)
2979 return r;
2980
2981 r = sd_event_source_set_priority(bus->output_io_event_source, bus->event_priority);
2982 } else
2983 r = sd_event_source_set_io_fd(bus->output_io_event_source, bus->output_fd);
2984
2985 if (r < 0)
2986 return r;
2987 }
2988
2989 return 0;
2990}
2991
2992static void detach_io_events(sd_bus *bus) {
2993 assert(bus);
2994
2995 if (bus->input_io_event_source) {
2996 sd_event_source_set_enabled(bus->input_io_event_source, SD_EVENT_OFF);
2997 bus->input_io_event_source = sd_event_source_unref(bus->input_io_event_source);
2998 }
2999
3000 if (bus->output_io_event_source) {
3001 sd_event_source_set_enabled(bus->output_io_event_source, SD_EVENT_OFF);
3002 bus->output_io_event_source = sd_event_source_unref(bus->output_io_event_source);
3003 }
3004}
3005
d9f644e2 3006_public_ int sd_bus_attach_event(sd_bus *bus, sd_event *event, int priority) {
40ca29a1
LP
3007 int r;
3008
3009 assert_return(bus, -EINVAL);
40ca29a1
LP
3010 assert_return(!bus->event, -EBUSY);
3011
3012 assert(!bus->input_io_event_source);
3013 assert(!bus->output_io_event_source);
3014 assert(!bus->time_event_source);
3015
76b54375
LP
3016 if (event)
3017 bus->event = sd_event_ref(event);
3018 else {
3019 r = sd_event_default(&bus->event);
3020 if (r < 0)
3021 return r;
3022 }
40ca29a1 3023
1e05d493 3024 bus->event_priority = priority;
40ca29a1 3025
151b9b96 3026 r = sd_event_add_monotonic(bus->event, &bus->time_event_source, 0, 0, time_callback, bus);
40ca29a1
LP
3027 if (r < 0)
3028 goto fail;
3029
3030 r = sd_event_source_set_priority(bus->time_event_source, priority);
3031 if (r < 0)
3032 goto fail;
3033
151b9b96 3034 r = sd_event_add_exit(bus->event, &bus->quit_event_source, quit_callback, bus);
abc5fe72
LP
3035 if (r < 0)
3036 goto fail;
3037
1e05d493
LP
3038 r = attach_io_events(bus);
3039 if (r < 0)
3040 goto fail;
3041
40ca29a1
LP
3042 return 0;
3043
3044fail:
3045 sd_bus_detach_event(bus);
3046 return r;
3047}
3048
d9f644e2 3049_public_ int sd_bus_detach_event(sd_bus *bus) {
40ca29a1 3050 assert_return(bus, -EINVAL);
a82cafb9
LP
3051
3052 if (!bus->event)
3053 return 0;
40ca29a1 3054
1e05d493 3055 detach_io_events(bus);
40ca29a1 3056
86befb40
LP
3057 if (bus->time_event_source) {
3058 sd_event_source_set_enabled(bus->time_event_source, SD_EVENT_OFF);
40ca29a1 3059 bus->time_event_source = sd_event_source_unref(bus->time_event_source);
86befb40 3060 }
40ca29a1 3061
86befb40
LP
3062 if (bus->quit_event_source) {
3063 sd_event_source_set_enabled(bus->quit_event_source, SD_EVENT_OFF);
abc5fe72 3064 bus->quit_event_source = sd_event_source_unref(bus->quit_event_source);
86befb40 3065 }
abc5fe72 3066
40ca29a1
LP
3067 if (bus->event)
3068 bus->event = sd_event_unref(bus->event);
3069
a82cafb9 3070 return 1;
40ca29a1 3071}
affff0b6 3072
2be44176
LP
3073_public_ sd_event* sd_bus_get_event(sd_bus *bus) {
3074 assert_return(bus, NULL);
3075
3076 return bus->event;
3077}
3078
76b54375 3079_public_ sd_bus_message* sd_bus_get_current(sd_bus *bus) {
affff0b6
LP
3080 assert_return(bus, NULL);
3081
3082 return bus->current;
3083}
76b54375
LP
3084
3085static int bus_default(int (*bus_open)(sd_bus **), sd_bus **default_bus, sd_bus **ret) {
3086 sd_bus *b = NULL;
3087 int r;
3088
3089 assert(bus_open);
3090 assert(default_bus);
3091
3092 if (!ret)
3093 return !!*default_bus;
3094
3095 if (*default_bus) {
3096 *ret = sd_bus_ref(*default_bus);
3097 return 0;
3098 }
3099
3100 r = bus_open(&b);
3101 if (r < 0)
3102 return r;
3103
3104 b->default_bus_ptr = default_bus;
3105 b->tid = gettid();
3106 *default_bus = b;
3107
3108 *ret = b;
3109 return 1;
3110}
3111
3112_public_ int sd_bus_default_system(sd_bus **ret) {
ec202eae 3113 static thread_local sd_bus *default_system_bus = NULL;
76b54375
LP
3114
3115 return bus_default(sd_bus_open_system, &default_system_bus, ret);
3116}
3117
3118_public_ int sd_bus_default_user(sd_bus **ret) {
ec202eae 3119 static thread_local sd_bus *default_user_bus = NULL;
76b54375
LP
3120
3121 return bus_default(sd_bus_open_user, &default_user_bus, ret);
3122}
3123
af08d2f9
LP
3124_public_ int sd_bus_default(sd_bus **ret) {
3125
3126 const char *e;
3127
3128 /* Let's try our best to reuse another cached connection. If
3129 * the starter bus type is set, connect via our normal
3130 * connection logic, ignoring $DBUS_STARTER_ADDRESS, so that
3131 * we can share the connection with the user/system default
3132 * bus. */
3133
3134 e = secure_getenv("DBUS_STARTER_BUS_TYPE");
3135 if (e) {
3136 if (streq(e, "system"))
3137 return sd_bus_default_system(ret);
09365592 3138 else if (STR_IN_SET(e, "user", "session"))
af08d2f9
LP
3139 return sd_bus_default_user(ret);
3140 }
3141
3142 /* No type is specified, so we have not other option than to
3143 * use the starter address if it is set. */
3144
3145 e = secure_getenv("DBUS_STARTER_ADDRESS");
3146 if (e) {
3147 static thread_local sd_bus *default_starter_bus = NULL;
3148
3149 return bus_default(sd_bus_open, &default_starter_bus, ret);
3150 }
3151
3152 /* Finally, if nothing is set use the cached connection for
3153 * the right scope */
3154
3155 if (cg_pid_get_owner_uid(0, NULL) >= 0)
3156 return sd_bus_default_user(ret);
3157 else
3158 return sd_bus_default_system(ret);
3159}
3160
76b54375
LP
3161_public_ int sd_bus_get_tid(sd_bus *b, pid_t *tid) {
3162 assert_return(b, -EINVAL);
3163 assert_return(tid, -EINVAL);
3164 assert_return(!bus_pid_changed(b), -ECHILD);
3165
3166 if (b->tid != 0) {
3167 *tid = b->tid;
3168 return 0;
3169 }
3170
3171 if (b->event)
3172 return sd_event_get_tid(b->event, tid);
3173
3174 return -ENXIO;
3175}
28383ba1 3176
a6278b88
LP
3177_public_ int sd_bus_path_encode(const char *prefix, const char *external_id, char **ret_path) {
3178 _cleanup_free_ char *e = NULL;
3179 char *ret;
3180
3181 assert_return(object_path_is_valid(prefix), -EINVAL);
3182 assert_return(external_id, -EINVAL);
3183 assert_return(ret_path, -EINVAL);
3184
3185 e = bus_label_escape(external_id);
3186 if (!e)
3187 return -ENOMEM;
3188
3189 ret = strjoin(prefix, "/", e, NULL);
3190 if (!ret)
3191 return -ENOMEM;
3192
3193 *ret_path = ret;
3194 return 0;
28383ba1
LP
3195}
3196
a6278b88
LP
3197_public_ int sd_bus_path_decode(const char *path, const char *prefix, char **external_id) {
3198 const char *e;
3199 char *ret;
3200
3201 assert_return(object_path_is_valid(path), -EINVAL);
3202 assert_return(object_path_is_valid(prefix), -EINVAL);
3203 assert_return(external_id, -EINVAL);
3204
3205 e = object_path_startswith(path, prefix);
3206 if (!e) {
3207 *external_id = NULL;
3208 return 0;
3209 }
3210
3211 ret = bus_label_unescape(e);
3212 if (!ret)
3213 return -ENOMEM;
3214
3215 *external_id = ret;
3216 return 1;
28383ba1 3217}
5b12334d
LP
3218
3219_public_ int sd_bus_get_peer_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **ret) {
3220 sd_bus_creds *c;
3221 pid_t pid = 0;
3222 int r;
3223
3224 assert_return(bus, -EINVAL);
95c4fe82 3225 assert_return(mask <= _SD_BUS_CREDS_ALL, -ENOTSUP);
5b12334d
LP
3226 assert_return(ret, -EINVAL);
3227 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
3228 assert_return(!bus_pid_changed(bus), -ECHILD);
3229 assert_return(!bus->is_kernel, -ENOTSUP);
3230
3231 if (!bus->ucred_valid && !isempty(bus->label))
3232 return -ENODATA;
3233
3234 c = bus_creds_new();
3235 if (!c)
3236 return -ENOMEM;
3237
3238 if (bus->ucred_valid) {
3239 pid = c->pid = bus->ucred.pid;
3240 c->uid = bus->ucred.uid;
3241 c->gid = bus->ucred.gid;
3242
3310dfd5 3243 c->mask |= (SD_BUS_CREDS_UID | SD_BUS_CREDS_PID | SD_BUS_CREDS_GID) & mask;
5b12334d
LP
3244 }
3245
3246 if (!isempty(bus->label) && (mask & SD_BUS_CREDS_SELINUX_CONTEXT)) {
3247 c->label = strdup(bus->label);
3248 if (!c->label) {
3249 sd_bus_creds_unref(c);
3250 return -ENOMEM;
3251 }
3252
3310dfd5 3253 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
5b12334d
LP
3254 }
3255
3256 r = bus_creds_add_more(c, mask, pid, 0);
3257 if (r < 0)
3258 return r;
3259
3260 *ret = c;
3261 return 0;
3262}
ae095f86
LP
3263
3264_public_ int sd_bus_try_close(sd_bus *bus) {
3265 int r;
3266
3267 assert_return(bus, -EINVAL);
3268 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
3269 assert_return(!bus_pid_changed(bus), -ECHILD);
3270 assert_return(bus->is_kernel, -ENOTSUP);
3271
bd746b8b
LP
3272 if (bus->rqueue_size > 0)
3273 return -EBUSY;
3274
14f862a5
LP
3275 if (bus->wqueue_size > 0)
3276 return -EBUSY;
3277
ae095f86
LP
3278 r = bus_kernel_try_close(bus);
3279 if (r < 0)
3280 return r;
3281
3282 sd_bus_close(bus);
3283 return 0;
3284}
5972fe95
LP
3285
3286_public_ int sd_bus_get_name(sd_bus *bus, const char **name) {
3287 assert_return(bus, -EINVAL);
3288 assert_return(name, -EINVAL);
3289 assert_return(!bus_pid_changed(bus), -ECHILD);
3290
3291 *name = bus->connection_name;
3292 return 0;
3293}