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