]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd-bus/sd-bus.c
bus: add api to control auto start message flag
[thirdparty/systemd.git] / src / libsystemd-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"
de1c301e
LP
37
38#include "sd-bus.h"
39#include "bus-internal.h"
40#include "bus-message.h"
41#include "bus-type.h"
a7e3212d 42#include "bus-socket.h"
6629161f 43#include "bus-kernel.h"
392d5b37 44#include "bus-control.h"
29ddb38f
LP
45#include "bus-introspect.h"
46#include "bus-signature.h"
992c052c 47#include "bus-objects.h"
40ca29a1 48#include "bus-util.h"
a7893c6b 49#include "bus-container.h"
de1c301e 50
e3017af9
LP
51static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec);
52
f54514f3
LP
53static void bus_close_fds(sd_bus *b) {
54 assert(b);
55
56 if (b->input_fd >= 0)
57 close_nointr_nofail(b->input_fd);
58
59 if (b->output_fd >= 0 && b->output_fd != b->input_fd)
60 close_nointr_nofail(b->output_fd);
61
62 b->input_fd = b->output_fd = -1;
63}
64
29ddb38f
LP
65static void bus_node_destroy(sd_bus *b, struct node *n) {
66 struct node_callback *c;
67 struct node_vtable *v;
68 struct node_enumerator *e;
69
70 assert(b);
71
72 if (!n)
73 return;
74
75 while (n->child)
76 bus_node_destroy(b, n->child);
77
78 while ((c = n->callbacks)) {
71fda00f 79 LIST_REMOVE(callbacks, n->callbacks, c);
29ddb38f
LP
80 free(c);
81 }
82
83 while ((v = n->vtables)) {
71fda00f 84 LIST_REMOVE(vtables, n->vtables, v);
29ddb38f
LP
85 free(v->interface);
86 free(v);
87 }
88
89 while ((e = n->enumerators)) {
71fda00f 90 LIST_REMOVE(enumerators, n->enumerators, e);
29ddb38f
LP
91 free(e);
92 }
93
94 if (n->parent)
71fda00f 95 LIST_REMOVE(siblings, n->parent->child, n);
29ddb38f
LP
96
97 assert_se(hashmap_remove(b->nodes, n->path) == n);
98 free(n->path);
99 free(n);
100}
101
de1c301e
LP
102static void bus_free(sd_bus *b) {
103 struct filter_callback *f;
29ddb38f 104 struct node *n;
89ffcd2a 105 unsigned i;
de1c301e
LP
106
107 assert(b);
108
40ca29a1
LP
109 sd_bus_detach_event(b);
110
f54514f3 111 bus_close_fds(b);
de1c301e 112
63edf05e
LP
113 if (b->kdbus_buffer)
114 munmap(b->kdbus_buffer, KDBUS_POOL_SIZE);
115
de1c301e 116 free(b->rbuffer);
89ffcd2a 117 free(b->unique_name);
2181a7f5 118 free(b->auth_buffer);
89ffcd2a 119 free(b->address);
e9a967f9 120 free(b->kernel);
a7893c6b 121 free(b->machine);
89ffcd2a 122
2fd9ae2e
LP
123 free(b->exec_path);
124 strv_free(b->exec_argv);
125
2c93b4ef
LP
126 close_many(b->fds, b->n_fds);
127 free(b->fds);
128
89ffcd2a
LP
129 for (i = 0; i < b->rqueue_size; i++)
130 sd_bus_message_unref(b->rqueue[i]);
de1c301e 131 free(b->rqueue);
89ffcd2a
LP
132
133 for (i = 0; i < b->wqueue_size; i++)
134 sd_bus_message_unref(b->wqueue[i]);
de1c301e 135 free(b->wqueue);
de1c301e
LP
136
137 hashmap_free_free(b->reply_callbacks);
e3017af9 138 prioq_free(b->reply_callbacks_prioq);
de1c301e
LP
139
140 while ((f = b->filter_callbacks)) {
71fda00f 141 LIST_REMOVE(callbacks, b->filter_callbacks, f);
de1c301e
LP
142 free(f);
143 }
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
150 while ((n = hashmap_first(b->nodes)))
151 bus_node_destroy(b, n);
152
153 hashmap_free(b->nodes);
154
bc7fd8cd
LP
155 bus_kernel_flush_memfd(b);
156
45fbe937
LP
157 assert_se(pthread_mutex_destroy(&b->memfd_cache_mutex) == 0);
158
de1c301e
LP
159 free(b);
160}
161
d9f644e2 162_public_ int sd_bus_new(sd_bus **ret) {
de1c301e
LP
163 sd_bus *r;
164
d6888822 165 assert_return(ret, -EINVAL);
021a1e78 166
de1c301e
LP
167 r = new0(sd_bus, 1);
168 if (!r)
021a1e78 169 return -ENOMEM;
de1c301e 170
e4ee6e5c 171 r->n_ref = REFCNT_INIT;
e82c9509 172 r->input_fd = r->output_fd = -1;
de1c301e 173 r->message_version = 1;
264ad849 174 r->hello_flags |= KDBUS_HELLO_ACCEPT_FD;
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 */
181 r->wqueue = new(sd_bus_message*, 1);
182 if (!r->wqueue) {
183 free(r);
021a1e78 184 return -ENOMEM;
de1c301e
LP
185 }
186
021a1e78
LP
187 *ret = r;
188 return 0;
189}
190
d9f644e2 191_public_ int sd_bus_set_address(sd_bus *bus, const char *address) {
021a1e78
LP
192 char *a;
193
d6888822
LP
194 assert_return(bus, -EINVAL);
195 assert_return(bus->state == BUS_UNSET, -EPERM);
196 assert_return(address, -EINVAL);
197 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78
LP
198
199 a = strdup(address);
200 if (!a)
201 return -ENOMEM;
202
203 free(bus->address);
204 bus->address = a;
205
206 return 0;
207}
208
d9f644e2 209_public_ int sd_bus_set_fd(sd_bus *bus, int input_fd, int output_fd) {
d6888822
LP
210 assert_return(bus, -EINVAL);
211 assert_return(bus->state == BUS_UNSET, -EPERM);
212 assert_return(input_fd >= 0, -EINVAL);
213 assert_return(output_fd >= 0, -EINVAL);
214 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78 215
e82c9509
LP
216 bus->input_fd = input_fd;
217 bus->output_fd = output_fd;
021a1e78
LP
218 return 0;
219}
220
d9f644e2 221_public_ int sd_bus_set_exec(sd_bus *bus, const char *path, char *const argv[]) {
2fd9ae2e
LP
222 char *p, **a;
223
d6888822
LP
224 assert_return(bus, -EINVAL);
225 assert_return(bus->state == BUS_UNSET, -EPERM);
226 assert_return(path, -EINVAL);
227 assert_return(!strv_isempty(argv), -EINVAL);
228 assert_return(!bus_pid_changed(bus), -ECHILD);
2fd9ae2e
LP
229
230 p = strdup(path);
231 if (!p)
232 return -ENOMEM;
233
234 a = strv_copy(argv);
235 if (!a) {
236 free(p);
237 return -ENOMEM;
238 }
239
240 free(bus->exec_path);
241 strv_free(bus->exec_argv);
242
243 bus->exec_path = p;
244 bus->exec_argv = a;
245
246 return 0;
247}
248
d9f644e2 249_public_ int sd_bus_set_bus_client(sd_bus *bus, int b) {
d6888822
LP
250 assert_return(bus, -EINVAL);
251 assert_return(bus->state == BUS_UNSET, -EPERM);
252 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78 253
94bbf1ba 254 bus->bus_client = !!b;
021a1e78
LP
255 return 0;
256}
257
d9f644e2 258_public_ int sd_bus_negotiate_fds(sd_bus *bus, int b) {
d6888822
LP
259 assert_return(bus, -EINVAL);
260 assert_return(bus->state == BUS_UNSET, -EPERM);
261 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78 262
264ad849
LP
263 SET_FLAG(bus->hello_flags, KDBUS_HELLO_ACCEPT_FD, b);
264 return 0;
265}
266
d9f644e2 267_public_ int sd_bus_negotiate_attach_comm(sd_bus *bus, int b) {
d6888822
LP
268 assert_return(bus, -EINVAL);
269 assert_return(bus->state == BUS_UNSET, -EPERM);
270 assert_return(!bus_pid_changed(bus), -ECHILD);
264ad849
LP
271
272 SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_COMM, b);
273 return 0;
274}
275
d9f644e2 276_public_ int sd_bus_negotiate_attach_exe(sd_bus *bus, int b) {
d6888822
LP
277 assert_return(bus, -EINVAL);
278 assert_return(bus->state == BUS_UNSET, -EPERM);
279 assert_return(!bus_pid_changed(bus), -ECHILD);
264ad849
LP
280
281 SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_EXE, b);
282 return 0;
283}
284
d9f644e2 285_public_ int sd_bus_negotiate_attach_cmdline(sd_bus *bus, int b) {
d6888822
LP
286 assert_return(bus, -EINVAL);
287 assert_return(bus->state == BUS_UNSET, -EPERM);
288 assert_return(!bus_pid_changed(bus), -ECHILD);
264ad849
LP
289
290 SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_CMDLINE, b);
291 return 0;
292}
293
d9f644e2 294_public_ int sd_bus_negotiate_attach_cgroup(sd_bus *bus, int b) {
d6888822
LP
295 assert_return(bus, -EINVAL);
296 assert_return(bus->state == BUS_UNSET, -EPERM);
297 assert_return(!bus_pid_changed(bus), -ECHILD);
264ad849
LP
298
299 SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_CGROUP, b);
300 return 0;
301}
302
d9f644e2 303_public_ int sd_bus_negotiate_attach_caps(sd_bus *bus, int b) {
d6888822
LP
304 assert_return(bus, -EINVAL);
305 assert_return(bus->state == BUS_UNSET, -EPERM);
306 assert_return(!bus_pid_changed(bus), -ECHILD);
264ad849
LP
307
308 SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_CAPS, b);
309 return 0;
310}
311
d9f644e2 312_public_ int sd_bus_negotiate_attach_selinux_context(sd_bus *bus, int b) {
d6888822
LP
313 assert_return(bus, -EINVAL);
314 assert_return(bus->state == BUS_UNSET, -EPERM);
315 assert_return(!bus_pid_changed(bus), -ECHILD);
264ad849
LP
316
317 SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_SECLABEL, b);
318 return 0;
319}
320
d9f644e2 321_public_ int sd_bus_negotiate_attach_audit(sd_bus *bus, int b) {
d6888822
LP
322 assert_return(bus, -EINVAL);
323 assert_return(bus->state == BUS_UNSET, -EPERM);
324 assert_return(!bus_pid_changed(bus), -ECHILD);
264ad849
LP
325
326 SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_AUDIT, b);
021a1e78
LP
327 return 0;
328}
de1c301e 329
d9f644e2 330_public_ int sd_bus_set_server(sd_bus *bus, int b, sd_id128_t server_id) {
d6888822
LP
331 assert_return(bus, -EINVAL);
332 assert_return(b || sd_id128_equal(server_id, SD_ID128_NULL), -EINVAL);
333 assert_return(bus->state == BUS_UNSET, -EPERM);
334 assert_return(!bus_pid_changed(bus), -ECHILD);
2181a7f5
LP
335
336 bus->is_server = !!b;
98178d39 337 bus->server_id = server_id;
2181a7f5
LP
338 return 0;
339}
340
d9f644e2 341_public_ int sd_bus_set_anonymous(sd_bus *bus, int b) {
d6888822
LP
342 assert_return(bus, -EINVAL);
343 assert_return(bus->state == BUS_UNSET, -EPERM);
344 assert_return(!bus_pid_changed(bus), -ECHILD);
2181a7f5
LP
345
346 bus->anonymous_auth = !!b;
347 return 0;
348}
349
eb01ba5d 350static int hello_callback(sd_bus *bus, sd_bus_message *reply, void *userdata) {
de1c301e
LP
351 const char *s;
352 int r;
353
354 assert(bus);
021a1e78 355 assert(bus->state == BUS_HELLO);
de1c301e
LP
356 assert(reply);
357
40ca29a1 358 r = sd_bus_message_get_errno(reply);
eb01ba5d
LP
359 if (r < 0)
360 return r;
40ca29a1
LP
361 if (r > 0)
362 return -r;
eb01ba5d 363
de1c301e
LP
364 r = sd_bus_message_read(reply, "s", &s);
365 if (r < 0)
366 return r;
367
dafb7591
LP
368 if (!service_name_is_valid(s) || s[0] != ':')
369 return -EBADMSG;
370
de1c301e
LP
371 bus->unique_name = strdup(s);
372 if (!bus->unique_name)
373 return -ENOMEM;
374
dafb7591
LP
375 bus->state = BUS_RUNNING;
376
de1c301e
LP
377 return 1;
378}
379
380static int bus_send_hello(sd_bus *bus) {
381 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
382 int r;
383
384 assert(bus);
385
6629161f 386 if (!bus->bus_client || bus->is_kernel)
021a1e78
LP
387 return 0;
388
de1c301e
LP
389 r = sd_bus_message_new_method_call(
390 bus,
391 "org.freedesktop.DBus",
392 "/",
393 "org.freedesktop.DBus",
394 "Hello",
395 &m);
396 if (r < 0)
397 return r;
398
c49b30a2 399 return sd_bus_call_async(bus, m, hello_callback, NULL, 0, &bus->hello_serial);
de1c301e
LP
400}
401
a7e3212d 402int bus_start_running(sd_bus *bus) {
de1c301e
LP
403 assert(bus);
404
f08838da 405 if (bus->bus_client && !bus->is_kernel) {
de1c301e 406 bus->state = BUS_HELLO;
e3017af9 407 return 1;
de1c301e
LP
408 }
409
410 bus->state = BUS_RUNNING;
e3017af9 411 return 1;
de1c301e
LP
412}
413
414static int parse_address_key(const char **p, const char *key, char **value) {
415 size_t l, n = 0;
416 const char *a;
417 char *r = NULL;
418
419 assert(p);
420 assert(*p);
de1c301e
LP
421 assert(value);
422
2fd9ae2e
LP
423 if (key) {
424 l = strlen(key);
425 if (strncmp(*p, key, l) != 0)
426 return 0;
de1c301e 427
2fd9ae2e
LP
428 if ((*p)[l] != '=')
429 return 0;
de1c301e 430
2fd9ae2e
LP
431 if (*value)
432 return -EINVAL;
de1c301e 433
2fd9ae2e
LP
434 a = *p + l + 1;
435 } else
436 a = *p;
437
438 while (*a != ';' && *a != ',' && *a != 0) {
de1c301e
LP
439 char c, *t;
440
441 if (*a == '%') {
442 int x, y;
443
444 x = unhexchar(a[1]);
445 if (x < 0) {
446 free(r);
447 return x;
448 }
449
450 y = unhexchar(a[2]);
451 if (y < 0) {
452 free(r);
453 return y;
454 }
455
de1c301e 456 c = (char) ((x << 4) | y);
89ffcd2a
LP
457 a += 3;
458 } else {
de1c301e 459 c = *a;
89ffcd2a
LP
460 a++;
461 }
de1c301e 462
89ffcd2a 463 t = realloc(r, n + 2);
de1c301e
LP
464 if (!t) {
465 free(r);
466 return -ENOMEM;
467 }
468
469 r = t;
470 r[n++] = c;
471 }
472
89ffcd2a
LP
473 if (!r) {
474 r = strdup("");
475 if (!r)
476 return -ENOMEM;
477 } else
478 r[n] = 0;
479
480 if (*a == ',')
481 a++;
482
de1c301e 483 *p = a;
2fd9ae2e
LP
484
485 free(*value);
de1c301e 486 *value = r;
2fd9ae2e 487
de1c301e
LP
488 return 1;
489}
490
491static void skip_address_key(const char **p) {
492 assert(p);
493 assert(*p);
494
89ffcd2a
LP
495 *p += strcspn(*p, ",");
496
497 if (**p == ',')
498 (*p) ++;
de1c301e
LP
499}
500
2fd9ae2e
LP
501static int parse_unix_address(sd_bus *b, const char **p, char **guid) {
502 _cleanup_free_ char *path = NULL, *abstract = NULL;
503 size_t l;
de1c301e
LP
504 int r;
505
506 assert(b);
2fd9ae2e
LP
507 assert(p);
508 assert(*p);
509 assert(guid);
de1c301e 510
2fd9ae2e
LP
511 while (**p != 0 && **p != ';') {
512 r = parse_address_key(p, "guid", guid);
513 if (r < 0)
514 return r;
515 else if (r > 0)
516 continue;
de1c301e 517
2fd9ae2e
LP
518 r = parse_address_key(p, "path", &path);
519 if (r < 0)
520 return r;
521 else if (r > 0)
522 continue;
de1c301e 523
2fd9ae2e
LP
524 r = parse_address_key(p, "abstract", &abstract);
525 if (r < 0)
526 return r;
527 else if (r > 0)
528 continue;
de1c301e 529
2fd9ae2e
LP
530 skip_address_key(p);
531 }
de1c301e 532
2fd9ae2e
LP
533 if (!path && !abstract)
534 return -EINVAL;
de1c301e 535
2fd9ae2e
LP
536 if (path && abstract)
537 return -EINVAL;
538
539 if (path) {
540 l = strlen(path);
541 if (l > sizeof(b->sockaddr.un.sun_path))
542 return -E2BIG;
de1c301e 543
2fd9ae2e
LP
544 b->sockaddr.un.sun_family = AF_UNIX;
545 strncpy(b->sockaddr.un.sun_path, path, sizeof(b->sockaddr.un.sun_path));
546 b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + l;
547 } else if (abstract) {
548 l = strlen(abstract);
549 if (l > sizeof(b->sockaddr.un.sun_path) - 1)
550 return -E2BIG;
551
552 b->sockaddr.un.sun_family = AF_UNIX;
553 b->sockaddr.un.sun_path[0] = 0;
554 strncpy(b->sockaddr.un.sun_path+1, abstract, sizeof(b->sockaddr.un.sun_path)-1);
555 b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + 1 + l;
556 }
557
558 return 0;
559}
560
561static int parse_tcp_address(sd_bus *b, const char **p, char **guid) {
562 _cleanup_free_ char *host = NULL, *port = NULL, *family = NULL;
2fd9ae2e 563 int r;
b92bea5d
ZJS
564 struct addrinfo *result, hints = {
565 .ai_socktype = SOCK_STREAM,
566 .ai_flags = AI_ADDRCONFIG,
567 };
2fd9ae2e
LP
568
569 assert(b);
570 assert(p);
571 assert(*p);
572 assert(guid);
573
574 while (**p != 0 && **p != ';') {
575 r = parse_address_key(p, "guid", guid);
576 if (r < 0)
577 return r;
578 else if (r > 0)
579 continue;
580
581 r = parse_address_key(p, "host", &host);
582 if (r < 0)
583 return r;
584 else if (r > 0)
585 continue;
586
587 r = parse_address_key(p, "port", &port);
588 if (r < 0)
589 return r;
590 else if (r > 0)
591 continue;
592
593 r = parse_address_key(p, "family", &family);
594 if (r < 0)
595 return r;
596 else if (r > 0)
597 continue;
598
599 skip_address_key(p);
600 }
601
602 if (!host || !port)
603 return -EINVAL;
604
2fd9ae2e
LP
605 if (family) {
606 if (streq(family, "ipv4"))
607 hints.ai_family = AF_INET;
608 else if (streq(family, "ipv6"))
609 hints.ai_family = AF_INET6;
610 else
611 return -EINVAL;
612 }
613
614 r = getaddrinfo(host, port, &hints, &result);
615 if (r == EAI_SYSTEM)
616 return -errno;
617 else if (r != 0)
618 return -EADDRNOTAVAIL;
619
620 memcpy(&b->sockaddr, result->ai_addr, result->ai_addrlen);
621 b->sockaddr_size = result->ai_addrlen;
622
623 freeaddrinfo(result);
624
625 return 0;
626}
627
628static int parse_exec_address(sd_bus *b, const char **p, char **guid) {
629 char *path = NULL;
630 unsigned n_argv = 0, j;
631 char **argv = NULL;
632 int r;
633
634 assert(b);
635 assert(p);
636 assert(*p);
637 assert(guid);
638
639 while (**p != 0 && **p != ';') {
640 r = parse_address_key(p, "guid", guid);
641 if (r < 0)
642 goto fail;
643 else if (r > 0)
644 continue;
645
646 r = parse_address_key(p, "path", &path);
647 if (r < 0)
648 goto fail;
649 else if (r > 0)
650 continue;
651
652 if (startswith(*p, "argv")) {
653 unsigned ul;
654
655 errno = 0;
656 ul = strtoul(*p + 4, (char**) p, 10);
8333c77e 657 if (errno > 0 || **p != '=' || ul > 256) {
2fd9ae2e
LP
658 r = -EINVAL;
659 goto fail;
660 }
661
662 (*p) ++;
663
664 if (ul >= n_argv) {
665 char **x;
666
667 x = realloc(argv, sizeof(char*) * (ul + 2));
668 if (!x) {
669 r = -ENOMEM;
670 goto fail;
671 }
672
673 memset(x + n_argv, 0, sizeof(char*) * (ul - n_argv + 2));
674
675 argv = x;
676 n_argv = ul + 1;
677 }
678
679 r = parse_address_key(p, NULL, argv + ul);
de1c301e 680 if (r < 0)
2fd9ae2e 681 goto fail;
de1c301e 682
2fd9ae2e 683 continue;
de1c301e
LP
684 }
685
2fd9ae2e
LP
686 skip_address_key(p);
687 }
de1c301e 688
5a0f6033
LP
689 if (!path) {
690 r = -EINVAL;
2fd9ae2e 691 goto fail;
5a0f6033 692 }
de1c301e 693
2fd9ae2e
LP
694 /* Make sure there are no holes in the array, with the
695 * exception of argv[0] */
696 for (j = 1; j < n_argv; j++)
697 if (!argv[j]) {
698 r = -EINVAL;
699 goto fail;
700 }
701
702 if (argv && argv[0] == NULL) {
703 argv[0] = strdup(path);
704 if (!argv[0]) {
705 r = -ENOMEM;
706 goto fail;
707 }
708 }
de1c301e 709
2fd9ae2e
LP
710 b->exec_path = path;
711 b->exec_argv = argv;
712 return 0;
de1c301e 713
2fd9ae2e
LP
714fail:
715 for (j = 0; j < n_argv; j++)
716 free(argv[j]);
717
718 free(argv);
719 free(path);
720 return r;
721}
722
6629161f
LP
723static int parse_kernel_address(sd_bus *b, const char **p, char **guid) {
724 _cleanup_free_ char *path = NULL;
725 int r;
726
727 assert(b);
728 assert(p);
729 assert(*p);
730 assert(guid);
731
732 while (**p != 0 && **p != ';') {
733 r = parse_address_key(p, "guid", guid);
734 if (r < 0)
735 return r;
736 else if (r > 0)
737 continue;
738
739 r = parse_address_key(p, "path", &path);
740 if (r < 0)
741 return r;
742 else if (r > 0)
743 continue;
744
745 skip_address_key(p);
746 }
747
748 if (!path)
749 return -EINVAL;
750
751 free(b->kernel);
752 b->kernel = path;
753 path = NULL;
754
755 return 0;
756}
757
a7893c6b
LP
758static int parse_container_address(sd_bus *b, const char **p, char **guid) {
759 _cleanup_free_ char *machine = NULL;
760 int r;
761
762 assert(b);
763 assert(p);
764 assert(*p);
765 assert(guid);
766
767 while (**p != 0 && **p != ';') {
768 r = parse_address_key(p, "guid", guid);
769 if (r < 0)
770 return r;
771 else if (r > 0)
772 continue;
773
774 r = parse_address_key(p, "machine", &machine);
775 if (r < 0)
776 return r;
777 else if (r > 0)
778 continue;
779
780 skip_address_key(p);
781 }
782
783 if (!machine)
784 return -EINVAL;
785
786 free(b->machine);
787 b->machine = machine;
788 machine = NULL;
789
790 b->sockaddr.un.sun_family = AF_UNIX;
791 strncpy(b->sockaddr.un.sun_path, "/var/run/dbus/system_bus_socket", sizeof(b->sockaddr.un.sun_path));
792 b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + sizeof("/var/run/dbus/system_bus_socket") - 1;
793
794 return 0;
795}
796
2fd9ae2e
LP
797static void bus_reset_parsed_address(sd_bus *b) {
798 assert(b);
799
800 zero(b->sockaddr);
801 b->sockaddr_size = 0;
802 strv_free(b->exec_argv);
803 free(b->exec_path);
804 b->exec_path = NULL;
805 b->exec_argv = NULL;
98178d39 806 b->server_id = SD_ID128_NULL;
6629161f
LP
807 free(b->kernel);
808 b->kernel = NULL;
a7893c6b
LP
809 free(b->machine);
810 b->machine = NULL;
2fd9ae2e
LP
811}
812
813static int bus_parse_next_address(sd_bus *b) {
814 _cleanup_free_ char *guid = NULL;
815 const char *a;
816 int r;
817
818 assert(b);
819
820 if (!b->address)
821 return 0;
822 if (b->address[b->address_index] == 0)
823 return 0;
824
825 bus_reset_parsed_address(b);
826
827 a = b->address + b->address_index;
de1c301e 828
2fd9ae2e 829 while (*a != 0) {
de1c301e 830
2fd9ae2e
LP
831 if (*a == ';') {
832 a++;
833 continue;
de1c301e
LP
834 }
835
2fd9ae2e
LP
836 if (startswith(a, "unix:")) {
837 a += 5;
de1c301e 838
2fd9ae2e 839 r = parse_unix_address(b, &a, &guid);
de1c301e
LP
840 if (r < 0)
841 return r;
2fd9ae2e 842 break;
de1c301e 843
2fd9ae2e 844 } else if (startswith(a, "tcp:")) {
de1c301e 845
2fd9ae2e
LP
846 a += 4;
847 r = parse_tcp_address(b, &a, &guid);
de1c301e
LP
848 if (r < 0)
849 return r;
de1c301e 850
2fd9ae2e
LP
851 break;
852
853 } else if (startswith(a, "unixexec:")) {
854
855 a += 9;
856 r = parse_exec_address(b, &a, &guid);
de1c301e
LP
857 if (r < 0)
858 return r;
de1c301e 859
2fd9ae2e 860 break;
de1c301e 861
6629161f
LP
862 } else if (startswith(a, "kernel:")) {
863
864 a += 7;
865 r = parse_kernel_address(b, &a, &guid);
866 if (r < 0)
867 return r;
868
a7893c6b
LP
869 break;
870 } else if (startswith(a, "x-container:")) {
871
872 a += 12;
873 r = parse_container_address(b, &a, &guid);
874 if (r < 0)
875 return r;
876
6629161f 877 break;
de1c301e
LP
878 }
879
2fd9ae2e
LP
880 a = strchr(a, ';');
881 if (!a)
882 return 0;
de1c301e
LP
883 }
884
885 if (guid) {
98178d39 886 r = sd_id128_from_string(guid, &b->server_id);
de1c301e
LP
887 if (r < 0)
888 return r;
889 }
890
2fd9ae2e 891 b->address_index = a - b->address;
de1c301e
LP
892 return 1;
893}
894
a7e3212d 895static int bus_start_address(sd_bus *b) {
2fd9ae2e
LP
896 int r;
897
898 assert(b);
899
900 for (;;) {
e82c9509 901 sd_bus_close(b);
2fd9ae2e 902
a7893c6b 903 if (b->exec_path) {
a7e3212d 904
a7893c6b 905 r = bus_socket_exec(b);
2fd9ae2e
LP
906 if (r >= 0)
907 return r;
908
909 b->last_connect_error = -r;
a7893c6b 910 } else if (b->kernel) {
2fd9ae2e 911
a7893c6b
LP
912 r = bus_kernel_connect(b);
913 if (r >= 0)
914 return r;
2fd9ae2e 915
a7893c6b
LP
916 b->last_connect_error = -r;
917
918 } else if (b->machine) {
919
920 r = bus_container_connect(b);
2fd9ae2e
LP
921 if (r >= 0)
922 return r;
923
6629161f 924 b->last_connect_error = -r;
6629161f 925
a7893c6b
LP
926 } else if (b->sockaddr.sa.sa_family != AF_UNSPEC) {
927
928 r = bus_socket_connect(b);
6629161f
LP
929 if (r >= 0)
930 return r;
931
2fd9ae2e
LP
932 b->last_connect_error = -r;
933 }
934
935 r = bus_parse_next_address(b);
936 if (r < 0)
937 return r;
938 if (r == 0)
939 return b->last_connect_error ? -b->last_connect_error : -ECONNREFUSED;
de1c301e
LP
940 }
941}
942
a7e3212d
LP
943int bus_next_address(sd_bus *b) {
944 assert(b);
945
946 bus_reset_parsed_address(b);
947 return bus_start_address(b);
948}
949
021a1e78 950static int bus_start_fd(sd_bus *b) {
6629161f 951 struct stat st;
021a1e78
LP
952 int r;
953
954 assert(b);
e82c9509
LP
955 assert(b->input_fd >= 0);
956 assert(b->output_fd >= 0);
021a1e78 957
e82c9509 958 r = fd_nonblock(b->input_fd, true);
021a1e78
LP
959 if (r < 0)
960 return r;
961
e82c9509 962 r = fd_cloexec(b->input_fd, true);
021a1e78
LP
963 if (r < 0)
964 return r;
965
e82c9509
LP
966 if (b->input_fd != b->output_fd) {
967 r = fd_nonblock(b->output_fd, true);
968 if (r < 0)
969 return r;
970
971 r = fd_cloexec(b->output_fd, true);
972 if (r < 0)
973 return r;
974 }
975
6629161f
LP
976 if (fstat(b->input_fd, &st) < 0)
977 return -errno;
978
979 if (S_ISCHR(b->input_fd))
980 return bus_kernel_take_fd(b);
981 else
982 return bus_socket_take_fd(b);
021a1e78
LP
983}
984
d9f644e2 985_public_ int sd_bus_start(sd_bus *bus) {
021a1e78
LP
986 int r;
987
d6888822
LP
988 assert_return(bus, -EINVAL);
989 assert_return(bus->state == BUS_UNSET, -EPERM);
990 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78
LP
991
992 bus->state = BUS_OPENING;
993
2181a7f5
LP
994 if (bus->is_server && bus->bus_client)
995 return -EINVAL;
996
e82c9509 997 if (bus->input_fd >= 0)
021a1e78 998 r = bus_start_fd(bus);
a7893c6b 999 else if (bus->address || bus->sockaddr.sa.sa_family != AF_UNSPEC || bus->exec_path || bus->kernel || bus->machine)
a7e3212d 1000 r = bus_start_address(bus);
021a1e78
LP
1001 else
1002 return -EINVAL;
1003
1004 if (r < 0)
1005 return r;
1006
1007 return bus_send_hello(bus);
1008}
1009
d9f644e2 1010_public_ int sd_bus_open_system(sd_bus **ret) {
de1c301e
LP
1011 const char *e;
1012 sd_bus *b;
1013 int r;
1014
d6888822 1015 assert_return(ret, -EINVAL);
de1c301e 1016
021a1e78
LP
1017 r = sd_bus_new(&b);
1018 if (r < 0)
1019 return r;
1020
6c03089c 1021 e = secure_getenv("DBUS_SYSTEM_BUS_ADDRESS");
de1c301e 1022 if (e) {
021a1e78 1023 r = sd_bus_set_address(b, e);
de1c301e 1024 if (r < 0)
021a1e78 1025 goto fail;
89ffcd2a 1026 } else {
89ffcd2a
LP
1027 b->sockaddr.un.sun_family = AF_UNIX;
1028 strncpy(b->sockaddr.un.sun_path, "/run/dbus/system_bus_socket", sizeof(b->sockaddr.un.sun_path));
1029 b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + sizeof("/run/dbus/system_bus_socket") - 1;
89ffcd2a 1030 }
de1c301e 1031
94bbf1ba 1032 b->bus_client = true;
021a1e78
LP
1033
1034 r = sd_bus_start(b);
1035 if (r < 0)
1036 goto fail;
de1c301e
LP
1037
1038 *ret = b;
1039 return 0;
021a1e78
LP
1040
1041fail:
1042 bus_free(b);
1043 return r;
de1c301e
LP
1044}
1045
d9f644e2 1046_public_ int sd_bus_open_user(sd_bus **ret) {
de1c301e
LP
1047 const char *e;
1048 sd_bus *b;
1049 size_t l;
1050 int r;
1051
d6888822 1052 assert_return(ret, -EINVAL);
de1c301e 1053
021a1e78
LP
1054 r = sd_bus_new(&b);
1055 if (r < 0)
1056 return r;
1057
6c03089c 1058 e = secure_getenv("DBUS_SESSION_BUS_ADDRESS");
de1c301e 1059 if (e) {
021a1e78 1060 r = sd_bus_set_address(b, e);
de1c301e 1061 if (r < 0)
021a1e78 1062 goto fail;
89ffcd2a 1063 } else {
6c03089c 1064 e = secure_getenv("XDG_RUNTIME_DIR");
021a1e78
LP
1065 if (!e) {
1066 r = -ENOENT;
1067 goto fail;
1068 }
de1c301e 1069
89ffcd2a 1070 l = strlen(e);
021a1e78
LP
1071 if (l + 4 > sizeof(b->sockaddr.un.sun_path)) {
1072 r = -E2BIG;
1073 goto fail;
1074 }
de1c301e 1075
89ffcd2a
LP
1076 b->sockaddr.un.sun_family = AF_UNIX;
1077 memcpy(mempcpy(b->sockaddr.un.sun_path, e, l), "/bus", 4);
1078 b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + l + 4;
de1c301e
LP
1079 }
1080
94bbf1ba 1081 b->bus_client = true;
de1c301e 1082
021a1e78 1083 r = sd_bus_start(b);
2571ead1
LP
1084 if (r < 0)
1085 goto fail;
de1c301e
LP
1086
1087 *ret = b;
1088 return 0;
2571ead1
LP
1089
1090fail:
021a1e78 1091 bus_free(b);
2571ead1 1092 return r;
de1c301e
LP
1093}
1094
d9f644e2 1095_public_ int sd_bus_open_system_remote(const char *host, sd_bus **ret) {
0f8bd8de
LP
1096 _cleanup_free_ char *e = NULL;
1097 char *p = NULL;
1098 sd_bus *bus;
1099 int r;
1100
1101 assert_return(host, -EINVAL);
1102 assert_return(ret, -EINVAL);
1103
1104 e = bus_address_escape(host);
1105 if (!e)
1106 return -ENOMEM;
1107
1108 p = strjoin("unixexec:path=ssh,argv1=-xT,argv2=", e, ",argv3=systemd-stdio-bridge", NULL);
1109 if (!p)
1110 return -ENOMEM;
a7893c6b
LP
1111
1112 r = sd_bus_new(&bus);
1113 if (r < 0) {
1114 free(p);
1115 return r;
1116 }
1117
1118 bus->address = p;
1119 bus->bus_client = true;
1120
1121 r = sd_bus_start(bus);
1122 if (r < 0) {
1123 bus_free(bus);
1124 return r;
1125 }
1126
1127 *ret = bus;
1128 return 0;
1129}
1130
d9f644e2 1131_public_ int sd_bus_open_system_container(const char *machine, sd_bus **ret) {
a7893c6b
LP
1132 _cleanup_free_ char *e = NULL;
1133 sd_bus *bus;
1134 char *p;
1135 int r;
1136
1137 assert_return(machine, -EINVAL);
1138 assert_return(ret, -EINVAL);
1139
1140 e = bus_address_escape(machine);
1141 if (!e)
1142 return -ENOMEM;
1143
1144 p = strjoin("x-container:machine=", e, NULL);
1145 if (!p)
1146 return -ENOMEM;
0f8bd8de
LP
1147
1148 r = sd_bus_new(&bus);
1149 if (r < 0) {
1150 free(p);
1151 return r;
1152 }
1153
1154 bus->address = p;
1155 bus->bus_client = true;
1156
1157 r = sd_bus_start(bus);
1158 if (r < 0) {
1159 bus_free(bus);
1160 return r;
1161 }
1162
1163 *ret = bus;
1164 return 0;
1165}
1166
d9f644e2 1167_public_ void sd_bus_close(sd_bus *bus) {
de1c301e
LP
1168 if (!bus)
1169 return;
d5a2b9a6
LP
1170 if (bus->state == BUS_CLOSED)
1171 return;
1172 if (bus_pid_changed(bus))
f54514f3
LP
1173 return;
1174
1175 bus->state = BUS_CLOSED;
e82c9509 1176
40ca29a1
LP
1177 sd_bus_detach_event(bus);
1178
f54514f3
LP
1179 if (!bus->is_kernel)
1180 bus_close_fds(bus);
1181
1182 /* We'll leave the fd open in case this is a kernel bus, since
1183 * there might still be memblocks around that reference this
1184 * bus, and they might need to invoke the
1185 * KDBUS_CMD_MSG_RELEASE ioctl on the fd when they are
1186 * freed. */
de1c301e
LP
1187}
1188
d9f644e2 1189_public_ sd_bus *sd_bus_ref(sd_bus *bus) {
9d6c7c82 1190 assert_return(bus, NULL);
de1c301e 1191
e4ee6e5c 1192 assert_se(REFCNT_INC(bus->n_ref) >= 2);
de1c301e 1193
de1c301e
LP
1194 return bus;
1195}
1196
d9f644e2 1197_public_ sd_bus *sd_bus_unref(sd_bus *bus) {
9d6c7c82 1198 assert_return(bus, NULL);
de1c301e 1199
e4ee6e5c 1200 if (REFCNT_DEC(bus->n_ref) <= 0)
de1c301e
LP
1201 bus_free(bus);
1202
1203 return NULL;
1204}
1205
d9f644e2 1206_public_ int sd_bus_is_open(sd_bus *bus) {
d6888822
LP
1207
1208 assert_return(bus, -EINVAL);
1209 assert_return(!bus_pid_changed(bus), -ECHILD);
e3017af9 1210
f54514f3 1211 return BUS_IS_OPEN(bus->state);
e3017af9
LP
1212}
1213
d9f644e2 1214_public_ int sd_bus_can_send(sd_bus *bus, char type) {
d728d708
LP
1215 int r;
1216
d6888822
LP
1217 assert_return(bus, -EINVAL);
1218 assert_return(bus->state != BUS_UNSET, -ENOTCONN);
1219 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 1220
d728d708 1221 if (type == SD_BUS_TYPE_UNIX_FD) {
264ad849 1222 if (!(bus->hello_flags & KDBUS_HELLO_ACCEPT_FD))
021a1e78
LP
1223 return 0;
1224
20902f3e 1225 r = bus_ensure_running(bus);
d728d708
LP
1226 if (r < 0)
1227 return r;
de1c301e 1228
d728d708
LP
1229 return bus->can_fds;
1230 }
1231
1232 return bus_type_is_valid(type);
de1c301e
LP
1233}
1234
d9f644e2 1235_public_ int sd_bus_get_server_id(sd_bus *bus, sd_id128_t *server_id) {
d728d708 1236 int r;
de1c301e 1237
d6888822
LP
1238 assert_return(bus, -EINVAL);
1239 assert_return(server_id, -EINVAL);
1240 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 1241
20902f3e 1242 r = bus_ensure_running(bus);
d728d708
LP
1243 if (r < 0)
1244 return r;
de1c301e 1245
98178d39 1246 *server_id = bus->server_id;
d728d708 1247 return 0;
de1c301e
LP
1248}
1249
1250static int bus_seal_message(sd_bus *b, sd_bus_message *m) {
1251 assert(m);
1252
89ffcd2a
LP
1253 if (m->header->version > b->message_version)
1254 return -EPERM;
1255
de1c301e
LP
1256 if (m->sealed)
1257 return 0;
1258
9a17484d 1259 return bus_message_seal(m, ++b->serial);
de1c301e
LP
1260}
1261
de1c301e 1262static int dispatch_wqueue(sd_bus *bus) {
e3017af9 1263 int r, ret = 0;
de1c301e
LP
1264
1265 assert(bus);
89ffcd2a 1266 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
de1c301e 1267
de1c301e
LP
1268 while (bus->wqueue_size > 0) {
1269
6629161f
LP
1270 if (bus->is_kernel)
1271 r = bus_kernel_write_message(bus, bus->wqueue[0]);
1272 else
1273 r = bus_socket_write_message(bus, bus->wqueue[0], &bus->windex);
1274
de1c301e
LP
1275 if (r < 0) {
1276 sd_bus_close(bus);
1277 return r;
1278 } else if (r == 0)
e3017af9
LP
1279 /* Didn't do anything this time */
1280 return ret;
6629161f 1281 else if (bus->is_kernel || bus->windex >= BUS_MESSAGE_SIZE(bus->wqueue[0])) {
de1c301e
LP
1282 /* Fully written. Let's drop the entry from
1283 * the queue.
1284 *
1285 * This isn't particularly optimized, but
1286 * well, this is supposed to be our worst-case
1287 * buffer only, and the socket buffer is
1288 * supposed to be our primary buffer, and if
1289 * it got full, then all bets are off
1290 * anyway. */
1291
1292 sd_bus_message_unref(bus->wqueue[0]);
1293 bus->wqueue_size --;
1294 memmove(bus->wqueue, bus->wqueue + 1, sizeof(sd_bus_message*) * bus->wqueue_size);
1295 bus->windex = 0;
1296
e3017af9 1297 ret = 1;
de1c301e
LP
1298 }
1299 }
1300
e3017af9 1301 return ret;
de1c301e
LP
1302}
1303
1304static int dispatch_rqueue(sd_bus *bus, sd_bus_message **m) {
2bf938c1 1305 sd_bus_message *z = NULL;
e3017af9 1306 int r, ret = 0;
de1c301e
LP
1307
1308 assert(bus);
1309 assert(m);
89ffcd2a 1310 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
de1c301e 1311
de1c301e
LP
1312 if (bus->rqueue_size > 0) {
1313 /* Dispatch a queued message */
1314
1315 *m = bus->rqueue[0];
1316 bus->rqueue_size --;
1317 memmove(bus->rqueue, bus->rqueue + 1, sizeof(sd_bus_message*) * bus->rqueue_size);
1318 return 1;
1319 }
1320
1321 /* Try to read a new message */
e3017af9 1322 do {
6629161f
LP
1323 if (bus->is_kernel)
1324 r = bus_kernel_read_message(bus, &z);
1325 else
1326 r = bus_socket_read_message(bus, &z);
1327
e3017af9
LP
1328 if (r < 0) {
1329 sd_bus_close(bus);
1330 return r;
1331 }
1332 if (r == 0)
1333 return ret;
de1c301e 1334
2e8d788c 1335 ret = 1;
e3017af9
LP
1336 } while (!z);
1337
1338 *m = z;
2e8d788c 1339 return ret;
de1c301e
LP
1340}
1341
d9f644e2 1342_public_ int sd_bus_send(sd_bus *bus, sd_bus_message *m, uint64_t *serial) {
de1c301e
LP
1343 int r;
1344
d6888822
LP
1345 assert_return(bus, -EINVAL);
1346 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
1347 assert_return(m, -EINVAL);
1348 assert_return(!bus_pid_changed(bus), -ECHILD);
021a1e78
LP
1349
1350 if (m->n_fds > 0) {
1351 r = sd_bus_can_send(bus, SD_BUS_TYPE_UNIX_FD);
1352 if (r < 0)
1353 return r;
1354 if (r == 0)
1355 return -ENOTSUP;
1356 }
de1c301e 1357
29f6aadd
LP
1358 /* If the serial number isn't kept, then we know that no reply
1359 * is expected */
1360 if (!serial && !m->sealed)
1361 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1362
de1c301e
LP
1363 r = bus_seal_message(bus, m);
1364 if (r < 0)
1365 return r;
1366
5407f2de
LP
1367 /* If this is a reply and no reply was requested, then let's
1368 * suppress this, if we can */
1369 if (m->dont_send && !serial)
7a37d625 1370 return 1;
5407f2de 1371
89ffcd2a 1372 if ((bus->state == BUS_RUNNING || bus->state == BUS_HELLO) && bus->wqueue_size <= 0) {
de1c301e
LP
1373 size_t idx = 0;
1374
6629161f
LP
1375 if (bus->is_kernel)
1376 r = bus_kernel_write_message(bus, m);
1377 else
1378 r = bus_socket_write_message(bus, m, &idx);
1379
de1c301e
LP
1380 if (r < 0) {
1381 sd_bus_close(bus);
1382 return r;
6629161f 1383 } else if (!bus->is_kernel && idx < BUS_MESSAGE_SIZE(m)) {
de1c301e
LP
1384 /* Wasn't fully written. So let's remember how
1385 * much was written. Note that the first entry
1386 * of the wqueue array is always allocated so
1387 * that we always can remember how much was
1388 * written. */
1389 bus->wqueue[0] = sd_bus_message_ref(m);
1390 bus->wqueue_size = 1;
1391 bus->windex = idx;
1392 }
1393 } else {
1394 sd_bus_message **q;
1395
1396 /* Just append it to the queue. */
1397
25220239 1398 if (bus->wqueue_size >= BUS_WQUEUE_MAX)
de1c301e
LP
1399 return -ENOBUFS;
1400
1401 q = realloc(bus->wqueue, sizeof(sd_bus_message*) * (bus->wqueue_size + 1));
1402 if (!q)
1403 return -ENOMEM;
1404
1405 bus->wqueue = q;
1406 q[bus->wqueue_size ++] = sd_bus_message_ref(m);
1407 }
1408
1409 if (serial)
1410 *serial = BUS_MESSAGE_SERIAL(m);
1411
7a37d625 1412 return 1;
de1c301e
LP
1413}
1414
1415static usec_t calc_elapse(uint64_t usec) {
1416 if (usec == (uint64_t) -1)
1417 return 0;
1418
1419 if (usec == 0)
e3017af9 1420 usec = BUS_DEFAULT_TIMEOUT;
de1c301e
LP
1421
1422 return now(CLOCK_MONOTONIC) + usec;
1423}
1424
e3017af9
LP
1425static int timeout_compare(const void *a, const void *b) {
1426 const struct reply_callback *x = a, *y = b;
1427
1428 if (x->timeout != 0 && y->timeout == 0)
1429 return -1;
1430
1431 if (x->timeout == 0 && y->timeout != 0)
1432 return 1;
1433
1434 if (x->timeout < y->timeout)
1435 return -1;
1436
1437 if (x->timeout > y->timeout)
1438 return 1;
1439
1440 return 0;
1441}
1442
c49b30a2 1443_public_ int sd_bus_call_async(
de1c301e
LP
1444 sd_bus *bus,
1445 sd_bus_message *m,
52f3ba91 1446 sd_bus_message_handler_t callback,
de1c301e
LP
1447 void *userdata,
1448 uint64_t usec,
1449 uint64_t *serial) {
1450
1451 struct reply_callback *c;
1452 int r;
1453
d6888822
LP
1454 assert_return(bus, -EINVAL);
1455 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
1456 assert_return(m, -EINVAL);
40ca29a1 1457 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
d6888822
LP
1458 assert_return(!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED), -EINVAL);
1459 assert_return(callback, -EINVAL);
1460 assert_return(!bus_pid_changed(bus), -ECHILD);
89ffcd2a
LP
1461
1462 r = hashmap_ensure_allocated(&bus->reply_callbacks, uint64_hash_func, uint64_compare_func);
1463 if (r < 0)
1464 return r;
de1c301e 1465
e3017af9
LP
1466 if (usec != (uint64_t) -1) {
1467 r = prioq_ensure_allocated(&bus->reply_callbacks_prioq, timeout_compare);
1468 if (r < 0)
1469 return r;
1470 }
1471
de1c301e
LP
1472 r = bus_seal_message(bus, m);
1473 if (r < 0)
1474 return r;
1475
eba8617e 1476 c = new0(struct reply_callback, 1);
de1c301e
LP
1477 if (!c)
1478 return -ENOMEM;
1479
1480 c->callback = callback;
1481 c->userdata = userdata;
1482 c->serial = BUS_MESSAGE_SERIAL(m);
1483 c->timeout = calc_elapse(usec);
1484
1485 r = hashmap_put(bus->reply_callbacks, &c->serial, c);
1486 if (r < 0) {
1487 free(c);
1488 return r;
1489 }
1490
e3017af9
LP
1491 if (c->timeout != 0) {
1492 r = prioq_put(bus->reply_callbacks_prioq, c, &c->prioq_idx);
1493 if (r < 0) {
1494 c->timeout = 0;
c49b30a2 1495 sd_bus_call_async_cancel(bus, c->serial);
e3017af9
LP
1496 return r;
1497 }
1498 }
1499
de1c301e
LP
1500 r = sd_bus_send(bus, m, serial);
1501 if (r < 0) {
c49b30a2 1502 sd_bus_call_async_cancel(bus, c->serial);
de1c301e
LP
1503 return r;
1504 }
1505
1506 return r;
1507}
1508
c49b30a2 1509_public_ int sd_bus_call_async_cancel(sd_bus *bus, uint64_t serial) {
e3017af9 1510 struct reply_callback *c;
de1c301e 1511
d6888822
LP
1512 assert_return(bus, -EINVAL);
1513 assert_return(serial != 0, -EINVAL);
1514 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e
LP
1515
1516 c = hashmap_remove(bus->reply_callbacks, &serial);
1517 if (!c)
1518 return 0;
1519
e3017af9
LP
1520 if (c->timeout != 0)
1521 prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
1522
de1c301e
LP
1523 free(c);
1524 return 1;
1525}
1526
20902f3e 1527int bus_ensure_running(sd_bus *bus) {
89ffcd2a
LP
1528 int r;
1529
1530 assert(bus);
1531
f54514f3 1532 if (bus->state == BUS_UNSET || bus->state == BUS_CLOSED)
021a1e78 1533 return -ENOTCONN;
d728d708
LP
1534 if (bus->state == BUS_RUNNING)
1535 return 1;
89ffcd2a
LP
1536
1537 for (;;) {
1538 r = sd_bus_process(bus, NULL);
1539 if (r < 0)
1540 return r;
d728d708
LP
1541 if (bus->state == BUS_RUNNING)
1542 return 1;
e3017af9
LP
1543 if (r > 0)
1544 continue;
89ffcd2a
LP
1545
1546 r = sd_bus_wait(bus, (uint64_t) -1);
1547 if (r < 0)
1548 return r;
1549 }
1550}
1551
c49b30a2 1552_public_ int sd_bus_call(
de1c301e
LP
1553 sd_bus *bus,
1554 sd_bus_message *m,
1555 uint64_t usec,
1556 sd_bus_error *error,
1557 sd_bus_message **reply) {
1558
1559 int r;
1560 usec_t timeout;
1561 uint64_t serial;
1562 bool room = false;
1563
d6888822
LP
1564 assert_return(bus, -EINVAL);
1565 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
1566 assert_return(m, -EINVAL);
40ca29a1 1567 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
d6888822
LP
1568 assert_return(!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED), -EINVAL);
1569 assert_return(!bus_error_is_dirty(error), -EINVAL);
1570 assert_return(!bus_pid_changed(bus), -ECHILD);
89ffcd2a 1571
20902f3e 1572 r = bus_ensure_running(bus);
89ffcd2a
LP
1573 if (r < 0)
1574 return r;
de1c301e
LP
1575
1576 r = sd_bus_send(bus, m, &serial);
1577 if (r < 0)
1578 return r;
1579
1580 timeout = calc_elapse(usec);
1581
1582 for (;;) {
1583 usec_t left;
e3017af9 1584 sd_bus_message *incoming = NULL;
de1c301e
LP
1585
1586 if (!room) {
1587 sd_bus_message **q;
1588
25220239
LP
1589 if (bus->rqueue_size >= BUS_RQUEUE_MAX)
1590 return -ENOBUFS;
1591
de1c301e
LP
1592 /* Make sure there's room for queuing this
1593 * locally, before we read the message */
1594
1595 q = realloc(bus->rqueue, (bus->rqueue_size + 1) * sizeof(sd_bus_message*));
1596 if (!q)
1597 return -ENOMEM;
1598
1599 bus->rqueue = q;
1600 room = true;
1601 }
1602
6629161f
LP
1603 if (bus->is_kernel)
1604 r = bus_kernel_read_message(bus, &incoming);
1605 else
1606 r = bus_socket_read_message(bus, &incoming);
de1c301e
LP
1607 if (r < 0)
1608 return r;
e3017af9 1609 if (incoming) {
89ffcd2a 1610
de1c301e
LP
1611 if (incoming->reply_serial == serial) {
1612 /* Found a match! */
1613
40ca29a1 1614 if (incoming->header->type == SD_BUS_MESSAGE_METHOD_RETURN) {
b7f247e0
LP
1615
1616 if (reply)
1617 *reply = incoming;
1618 else
1619 sd_bus_message_unref(incoming);
1620
7a37d625 1621 return 1;
de1c301e
LP
1622 }
1623
40ca29a1 1624 if (incoming->header->type == SD_BUS_MESSAGE_METHOD_ERROR) {
de1c301e
LP
1625 int k;
1626
1627 r = sd_bus_error_copy(error, &incoming->error);
1628 if (r < 0) {
1629 sd_bus_message_unref(incoming);
1630 return r;
1631 }
1632
40ca29a1 1633 k = sd_bus_error_get_errno(&incoming->error);
de1c301e 1634 sd_bus_message_unref(incoming);
40ca29a1 1635 return -k;
de1c301e
LP
1636 }
1637
1638 sd_bus_message_unref(incoming);
1639 return -EIO;
1640 }
1641
1642 /* There's already guaranteed to be room for
1643 * this, so need to resize things here */
1644 bus->rqueue[bus->rqueue_size ++] = incoming;
1645 room = false;
1646
1647 /* Try to read more, right-away */
1648 continue;
1649 }
e3017af9
LP
1650 if (r != 0)
1651 continue;
de1c301e
LP
1652
1653 if (timeout > 0) {
1654 usec_t n;
1655
1656 n = now(CLOCK_MONOTONIC);
1657 if (n >= timeout)
1658 return -ETIMEDOUT;
1659
1660 left = timeout - n;
1661 } else
1662 left = (uint64_t) -1;
1663
e3017af9 1664 r = bus_poll(bus, true, left);
de1c301e
LP
1665 if (r < 0)
1666 return r;
1667
1668 r = dispatch_wqueue(bus);
1669 if (r < 0)
1670 return r;
1671 }
1672}
1673
d9f644e2 1674_public_ int sd_bus_get_fd(sd_bus *bus) {
d6888822
LP
1675
1676 assert_return(bus, -EINVAL);
1677 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
1678 assert_return(bus->input_fd == bus->output_fd, -EPERM);
1679 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 1680
e82c9509 1681 return bus->input_fd;
de1c301e
LP
1682}
1683
d9f644e2 1684_public_ int sd_bus_get_events(sd_bus *bus) {
de1c301e
LP
1685 int flags = 0;
1686
d6888822
LP
1687 assert_return(bus, -EINVAL);
1688 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
1689 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e
LP
1690
1691 if (bus->state == BUS_OPENING)
1692 flags |= POLLOUT;
89ffcd2a
LP
1693 else if (bus->state == BUS_AUTHENTICATING) {
1694
2181a7f5 1695 if (bus_socket_auth_needs_write(bus))
89ffcd2a
LP
1696 flags |= POLLOUT;
1697
1698 flags |= POLLIN;
1699
1700 } else if (bus->state == BUS_RUNNING || bus->state == BUS_HELLO) {
de1c301e
LP
1701 if (bus->rqueue_size <= 0)
1702 flags |= POLLIN;
1703 if (bus->wqueue_size > 0)
1704 flags |= POLLOUT;
1705 }
1706
1707 return flags;
1708}
1709
d9f644e2 1710_public_ int sd_bus_get_timeout(sd_bus *bus, uint64_t *timeout_usec) {
e3017af9
LP
1711 struct reply_callback *c;
1712
d6888822
LP
1713 assert_return(bus, -EINVAL);
1714 assert_return(timeout_usec, -EINVAL);
1715 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
1716 assert_return(!bus_pid_changed(bus), -ECHILD);
e3017af9
LP
1717
1718 if (bus->state == BUS_AUTHENTICATING) {
1719 *timeout_usec = bus->auth_timeout;
1720 return 1;
1721 }
1722
adee69fa
LP
1723 if (bus->state != BUS_RUNNING && bus->state != BUS_HELLO) {
1724 *timeout_usec = (uint64_t) -1;
e3017af9 1725 return 0;
adee69fa 1726 }
e3017af9 1727
8efd6381
LP
1728 if (bus->rqueue_size > 0) {
1729 *timeout_usec = 0;
1730 return 1;
1731 }
1732
e3017af9 1733 c = prioq_peek(bus->reply_callbacks_prioq);
adee69fa
LP
1734 if (!c) {
1735 *timeout_usec = (uint64_t) -1;
e3017af9 1736 return 0;
adee69fa 1737 }
e3017af9
LP
1738
1739 *timeout_usec = c->timeout;
1740 return 1;
1741}
1742
1743static int process_timeout(sd_bus *bus) {
eb01ba5d 1744 _cleanup_bus_message_unref_ sd_bus_message* m = NULL;
e3017af9
LP
1745 struct reply_callback *c;
1746 usec_t n;
1747 int r;
1748
1749 assert(bus);
1750
1751 c = prioq_peek(bus->reply_callbacks_prioq);
1752 if (!c)
1753 return 0;
1754
1755 n = now(CLOCK_MONOTONIC);
1756 if (c->timeout > n)
1757 return 0;
1758
eb01ba5d
LP
1759 r = bus_message_new_synthetic_error(
1760 bus,
1761 c->serial,
40ca29a1 1762 &SD_BUS_ERROR_MAKE(SD_BUS_ERROR_NO_REPLY, "Method call timed out"),
eb01ba5d
LP
1763 &m);
1764 if (r < 0)
1765 return r;
1766
e3017af9
LP
1767 assert_se(prioq_pop(bus->reply_callbacks_prioq) == c);
1768 hashmap_remove(bus->reply_callbacks, &c->serial);
1769
eb01ba5d 1770 r = c->callback(bus, m, c->userdata);
e3017af9
LP
1771 free(c);
1772
1773 return r < 0 ? r : 1;
1774}
1775
9d373862
LP
1776static int process_hello(sd_bus *bus, sd_bus_message *m) {
1777 assert(bus);
1778 assert(m);
1779
1780 if (bus->state != BUS_HELLO)
1781 return 0;
1782
1783 /* Let's make sure the first message on the bus is the HELLO
1784 * reply. But note that we don't actually parse the message
2181a7f5
LP
1785 * here (we leave that to the usual handling), we just verify
1786 * we don't let any earlier msg through. */
9d373862 1787
40ca29a1
LP
1788 if (m->header->type != SD_BUS_MESSAGE_METHOD_RETURN &&
1789 m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
9d373862
LP
1790 return -EIO;
1791
1792 if (m->reply_serial != bus->hello_serial)
1793 return -EIO;
1794
1795 return 0;
1796}
1797
a652755d
LP
1798static int process_reply(sd_bus *bus, sd_bus_message *m) {
1799 struct reply_callback *c;
1800 int r;
1801
1802 assert(bus);
1803 assert(m);
1804
40ca29a1
LP
1805 if (m->header->type != SD_BUS_MESSAGE_METHOD_RETURN &&
1806 m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
a652755d
LP
1807 return 0;
1808
1809 c = hashmap_remove(bus->reply_callbacks, &m->reply_serial);
1810 if (!c)
1811 return 0;
1812
1813 if (c->timeout != 0)
1814 prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
1815
88fe224c
LP
1816 r = sd_bus_message_rewind(m, true);
1817 if (r < 0)
1818 return r;
1819
eb01ba5d 1820 r = c->callback(bus, m, c->userdata);
a652755d
LP
1821 free(c);
1822
1823 return r;
1824}
1825
1826static int process_filter(sd_bus *bus, sd_bus_message *m) {
1827 struct filter_callback *l;
1828 int r;
1829
392d5b37
LP
1830 assert(bus);
1831 assert(m);
1832
7286037f
LP
1833 do {
1834 bus->filter_callbacks_modified = false;
1835
1836 LIST_FOREACH(callbacks, l, bus->filter_callbacks) {
1837
1838 if (bus->filter_callbacks_modified)
1839 break;
1840
1841 /* Don't run this more than once per iteration */
1842 if (l->last_iteration == bus->iteration_counter)
1843 continue;
1844
1845 l->last_iteration = bus->iteration_counter;
1846
88fe224c
LP
1847 r = sd_bus_message_rewind(m, true);
1848 if (r < 0)
1849 return r;
1850
eb01ba5d 1851 r = l->callback(bus, m, l->userdata);
7286037f
LP
1852 if (r != 0)
1853 return r;
1854
1855 }
1856
1857 } while (bus->filter_callbacks_modified);
a652755d
LP
1858
1859 return 0;
1860}
1861
392d5b37 1862static int process_match(sd_bus *bus, sd_bus_message *m) {
7286037f
LP
1863 int r;
1864
392d5b37
LP
1865 assert(bus);
1866 assert(m);
1867
7286037f
LP
1868 do {
1869 bus->match_callbacks_modified = false;
1870
eb01ba5d 1871 r = bus_match_run(bus, &bus->match_callbacks, m);
7286037f
LP
1872 if (r != 0)
1873 return r;
1874
1875 } while (bus->match_callbacks_modified);
1876
1877 return 0;
392d5b37
LP
1878}
1879
b9bf7e2b
LP
1880static int process_builtin(sd_bus *bus, sd_bus_message *m) {
1881 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1882 int r;
1883
1884 assert(bus);
1885 assert(m);
1886
40ca29a1 1887 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
b9bf7e2b
LP
1888 return 0;
1889
1890 if (!streq_ptr(m->interface, "org.freedesktop.DBus.Peer"))
1891 return 0;
1892
1893 if (m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED)
1894 return 1;
1895
1896 if (streq_ptr(m->member, "Ping"))
1897 r = sd_bus_message_new_method_return(bus, m, &reply);
1898 else if (streq_ptr(m->member, "GetMachineId")) {
1899 sd_id128_t id;
1900 char sid[33];
1901
1902 r = sd_id128_get_machine(&id);
1903 if (r < 0)
1904 return r;
1905
1906 r = sd_bus_message_new_method_return(bus, m, &reply);
1907 if (r < 0)
1908 return r;
1909
1910 r = sd_bus_message_append(reply, "s", sd_id128_to_string(id, sid));
1911 } else {
29ddb38f
LP
1912 r = sd_bus_message_new_method_errorf(
1913 bus, m, &reply,
40ca29a1 1914 SD_BUS_ERROR_UNKNOWN_METHOD,
b9bf7e2b 1915 "Unknown method '%s' on interface '%s'.", m->member, m->interface);
b9bf7e2b
LP
1916 }
1917
1918 if (r < 0)
1919 return r;
1920
1921 r = sd_bus_send(bus, reply, NULL);
1922 if (r < 0)
1923 return r;
1924
1925 return 1;
1926}
1927
992c052c 1928static int process_message(sd_bus *bus, sd_bus_message *m) {
e3017af9
LP
1929 int r;
1930
1931 assert(bus);
992c052c 1932 assert(m);
e3017af9 1933
affff0b6 1934 bus->current = m;
992c052c 1935 bus->iteration_counter++;
e3017af9 1936
40ca29a1
LP
1937 log_debug("Got message sender=%s object=%s interface=%s member=%s",
1938 strna(sd_bus_message_get_sender(m)),
1939 strna(sd_bus_message_get_path(m)),
1940 strna(sd_bus_message_get_interface(m)),
1941 strna(sd_bus_message_get_member(m)));
1942
992c052c
LP
1943 r = process_hello(bus, m);
1944 if (r != 0)
affff0b6 1945 goto finish;
a652755d 1946
992c052c
LP
1947 r = process_reply(bus, m);
1948 if (r != 0)
affff0b6 1949 goto finish;
e3017af9 1950
992c052c
LP
1951 r = process_filter(bus, m);
1952 if (r != 0)
affff0b6 1953 goto finish;
a652755d 1954
992c052c
LP
1955 r = process_match(bus, m);
1956 if (r != 0)
affff0b6 1957 goto finish;
a652755d 1958
992c052c
LP
1959 r = process_builtin(bus, m);
1960 if (r != 0)
affff0b6
LP
1961 goto finish;
1962
1963 r = bus_process_object(bus, m);
a652755d 1964
affff0b6
LP
1965finish:
1966 bus->current = NULL;
1967 return r;
29ddb38f 1968}
88fe224c 1969
992c052c
LP
1970static int process_running(sd_bus *bus, sd_bus_message **ret) {
1971 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
29ddb38f 1972 int r;
a652755d 1973
29ddb38f 1974 assert(bus);
992c052c 1975 assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
7286037f 1976
992c052c
LP
1977 r = process_timeout(bus);
1978 if (r != 0)
1979 goto null_message;
7286037f 1980
992c052c
LP
1981 r = dispatch_wqueue(bus);
1982 if (r != 0)
1983 goto null_message;
7286037f 1984
992c052c
LP
1985 r = dispatch_rqueue(bus, &m);
1986 if (r < 0)
1987 return r;
1988 if (!m)
1989 goto null_message;
7286037f 1990
992c052c
LP
1991 r = process_message(bus, m);
1992 if (r != 0)
1993 goto null_message;
7286037f 1994
992c052c
LP
1995 if (ret) {
1996 r = sd_bus_message_rewind(m, true);
29ddb38f
LP
1997 if (r < 0)
1998 return r;
e3017af9 1999
992c052c
LP
2000 *ret = m;
2001 m = NULL;
2002 return 1;
2003 }
a652755d 2004
40ca29a1 2005 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL) {
a652755d 2006
992c052c
LP
2007 r = sd_bus_reply_method_errorf(
2008 bus, m,
40ca29a1 2009 SD_BUS_ERROR_UNKNOWN_OBJECT,
992c052c 2010 "Unknown object '%s'.", m->path);
29ddb38f
LP
2011 if (r < 0)
2012 return r;
2013 }
e3017af9 2014
992c052c 2015 return 1;
0a72c2bd 2016
992c052c
LP
2017null_message:
2018 if (r >= 0 && ret)
2019 *ret = NULL;
0a72c2bd 2020
992c052c 2021 return r;
29ddb38f 2022}
0a72c2bd 2023
d9f644e2 2024_public_ int sd_bus_process(sd_bus *bus, sd_bus_message **ret) {
8ce2afd6 2025 BUS_DONT_DESTROY(bus);
29ddb38f 2026 int r;
0a72c2bd 2027
992c052c
LP
2028 /* Returns 0 when we didn't do anything. This should cause the
2029 * caller to invoke sd_bus_wait() before returning the next
2030 * time. Returns > 0 when we did something, which possibly
2031 * means *ret is filled in with an unprocessed message. */
0a72c2bd 2032
d6888822
LP
2033 assert_return(bus, -EINVAL);
2034 assert_return(!bus_pid_changed(bus), -ECHILD);
0a72c2bd 2035
992c052c 2036 /* We don't allow recursively invoking sd_bus_process(). */
d6888822 2037 assert_return(!bus->processing, -EBUSY);
0a72c2bd 2038
992c052c 2039 switch (bus->state) {
0a72c2bd 2040
992c052c
LP
2041 case BUS_UNSET:
2042 case BUS_CLOSED:
2043 return -ENOTCONN;
0a72c2bd 2044
992c052c
LP
2045 case BUS_OPENING:
2046 r = bus_socket_process_opening(bus);
2047 if (r < 0)
29ddb38f 2048 return r;
992c052c
LP
2049 if (ret)
2050 *ret = NULL;
a652755d
LP
2051 return r;
2052
992c052c 2053 case BUS_AUTHENTICATING:
392d5b37 2054
992c052c 2055 r = bus_socket_process_authenticating(bus);
29ddb38f
LP
2056 if (r < 0)
2057 return r;
992c052c
LP
2058 if (ret)
2059 *ret = NULL;
2060 return r;
a652755d 2061
992c052c
LP
2062 case BUS_RUNNING:
2063 case BUS_HELLO:
0a72c2bd 2064
992c052c
LP
2065 bus->processing = true;
2066 r = process_running(bus, ret);
2067 bus->processing = false;
43a43f50 2068
43a43f50 2069 return r;
992c052c 2070 }
43a43f50 2071
992c052c 2072 assert_not_reached("Unknown state");
e3017af9
LP
2073}
2074
992c052c
LP
2075static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec) {
2076 struct pollfd p[2] = {};
2077 int r, e, n;
2078 struct timespec ts;
8efd6381 2079 usec_t m = (usec_t) -1;
adcdb374
LP
2080
2081 assert(bus);
d6888822 2082 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
adcdb374 2083
992c052c
LP
2084 e = sd_bus_get_events(bus);
2085 if (e < 0)
2086 return e;
adcdb374 2087
992c052c 2088 if (need_more)
8efd6381
LP
2089 /* The caller really needs some more data, he doesn't
2090 * care about what's already read, or any timeouts
2091 * except its own.*/
992c052c 2092 e |= POLLIN;
992c052c 2093 else {
8efd6381
LP
2094 usec_t until;
2095 /* The caller wants to process if there's something to
2096 * process, but doesn't care otherwise */
2097
2098 r = sd_bus_get_timeout(bus, &until);
2099 if (r < 0)
2100 return r;
2101 if (r > 0) {
2102 usec_t nw;
2103 nw = now(CLOCK_MONOTONIC);
2104 m = until > nw ? until - nw : 0;
2105 }
992c052c 2106 }
adcdb374 2107
992c052c
LP
2108 if (timeout_usec != (uint64_t) -1 && (m == (uint64_t) -1 || timeout_usec < m))
2109 m = timeout_usec;
adcdb374 2110
992c052c
LP
2111 p[0].fd = bus->input_fd;
2112 if (bus->output_fd == bus->input_fd) {
2113 p[0].events = e;
2114 n = 1;
2115 } else {
2116 p[0].events = e & POLLIN;
2117 p[1].fd = bus->output_fd;
2118 p[1].events = e & POLLOUT;
2119 n = 2;
adcdb374
LP
2120 }
2121
992c052c 2122 r = ppoll(p, n, m == (uint64_t) -1 ? NULL : timespec_store(&ts, m), NULL);
adcdb374 2123 if (r < 0)
992c052c 2124 return -errno;
adcdb374 2125
992c052c 2126 return r > 0 ? 1 : 0;
adcdb374
LP
2127}
2128
d9f644e2 2129_public_ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) {
9db76355 2130
d6888822
LP
2131 assert_return(bus, -EINVAL);
2132 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
2133 assert_return(!bus_pid_changed(bus), -ECHILD);
9db76355 2134
992c052c
LP
2135 if (bus->rqueue_size > 0)
2136 return 0;
9db76355 2137
992c052c
LP
2138 return bus_poll(bus, false, timeout_usec);
2139}
9db76355 2140
d9f644e2 2141_public_ int sd_bus_flush(sd_bus *bus) {
992c052c 2142 int r;
9db76355 2143
d6888822
LP
2144 assert_return(bus, -EINVAL);
2145 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
2146 assert_return(!bus_pid_changed(bus), -ECHILD);
9db76355 2147
992c052c
LP
2148 r = bus_ensure_running(bus);
2149 if (r < 0)
2150 return r;
9db76355 2151
992c052c
LP
2152 if (bus->wqueue_size <= 0)
2153 return 0;
9db76355 2154
992c052c
LP
2155 for (;;) {
2156 r = dispatch_wqueue(bus);
9db76355
LP
2157 if (r < 0)
2158 return r;
2159
992c052c
LP
2160 if (bus->wqueue_size <= 0)
2161 return 0;
9db76355 2162
992c052c 2163 r = bus_poll(bus, false, (uint64_t) -1);
9db76355
LP
2164 if (r < 0)
2165 return r;
9db76355 2166 }
9db76355
LP
2167}
2168
d9f644e2
ZJS
2169_public_ int sd_bus_add_filter(sd_bus *bus,
2170 sd_bus_message_handler_t callback,
2171 void *userdata) {
2172
992c052c 2173 struct filter_callback *f;
de1c301e 2174
d6888822
LP
2175 assert_return(bus, -EINVAL);
2176 assert_return(callback, -EINVAL);
2177 assert_return(!bus_pid_changed(bus), -ECHILD);
de1c301e 2178
992c052c
LP
2179 f = new0(struct filter_callback, 1);
2180 if (!f)
29ddb38f 2181 return -ENOMEM;
992c052c
LP
2182 f->callback = callback;
2183 f->userdata = userdata;
29ddb38f 2184
992c052c 2185 bus->filter_callbacks_modified = true;
71fda00f 2186 LIST_PREPEND(callbacks, bus->filter_callbacks, f);
de1c301e
LP
2187 return 0;
2188}
a652755d 2189
d9f644e2
ZJS
2190_public_ int sd_bus_remove_filter(sd_bus *bus,
2191 sd_bus_message_handler_t callback,
2192 void *userdata) {
2193
992c052c 2194 struct filter_callback *f;
a652755d 2195
d6888822
LP
2196 assert_return(bus, -EINVAL);
2197 assert_return(callback, -EINVAL);
2198 assert_return(!bus_pid_changed(bus), -ECHILD);
a652755d 2199
992c052c
LP
2200 LIST_FOREACH(callbacks, f, bus->filter_callbacks) {
2201 if (f->callback == callback && f->userdata == userdata) {
2202 bus->filter_callbacks_modified = true;
71fda00f 2203 LIST_REMOVE(callbacks, bus->filter_callbacks, f);
992c052c
LP
2204 free(f);
2205 return 1;
29ddb38f
LP
2206 }
2207 }
2208
992c052c 2209 return 0;
a652755d 2210}
392d5b37 2211
d9f644e2
ZJS
2212_public_ int sd_bus_add_match(sd_bus *bus,
2213 const char *match,
2214 sd_bus_message_handler_t callback,
2215 void *userdata) {
2216
992c052c
LP
2217 struct bus_match_component *components = NULL;
2218 unsigned n_components = 0;
2219 uint64_t cookie = 0;
2220 int r = 0;
392d5b37 2221
d6888822
LP
2222 assert_return(bus, -EINVAL);
2223 assert_return(match, -EINVAL);
2224 assert_return(!bus_pid_changed(bus), -ECHILD);
392d5b37 2225
992c052c
LP
2226 r = bus_match_parse(match, &components, &n_components);
2227 if (r < 0)
2228 goto finish;
29ddb38f 2229
992c052c
LP
2230 if (bus->bus_client) {
2231 cookie = ++bus->match_cookie;
29ddb38f 2232
992c052c
LP
2233 r = bus_add_match_internal(bus, match, components, n_components, cookie);
2234 if (r < 0)
2235 goto finish;
392d5b37
LP
2236 }
2237
992c052c
LP
2238 bus->match_callbacks_modified = true;
2239 r = bus_match_add(&bus->match_callbacks, components, n_components, callback, userdata, cookie, NULL);
29ddb38f 2240 if (r < 0) {
992c052c
LP
2241 if (bus->bus_client)
2242 bus_remove_match_internal(bus, match, cookie);
29ddb38f 2243 }
917b5dc7 2244
992c052c
LP
2245finish:
2246 bus_match_parse_free(components, n_components);
2247 return r;
917b5dc7
LP
2248}
2249
d9f644e2
ZJS
2250_public_ int sd_bus_remove_match(sd_bus *bus,
2251 const char *match,
2252 sd_bus_message_handler_t callback,
2253 void *userdata) {
2254
992c052c
LP
2255 struct bus_match_component *components = NULL;
2256 unsigned n_components = 0;
2257 int r = 0, q = 0;
2258 uint64_t cookie = 0;
917b5dc7 2259
d6888822
LP
2260 assert_return(bus, -EINVAL);
2261 assert_return(match, -EINVAL);
2262 assert_return(!bus_pid_changed(bus), -ECHILD);
917b5dc7 2263
992c052c 2264 r = bus_match_parse(match, &components, &n_components);
29ddb38f
LP
2265 if (r < 0)
2266 return r;
f10dda3b 2267
992c052c
LP
2268 bus->match_callbacks_modified = true;
2269 r = bus_match_remove(&bus->match_callbacks, components, n_components, callback, userdata, &cookie);
f10dda3b 2270
992c052c
LP
2271 if (bus->bus_client)
2272 q = bus_remove_match_internal(bus, match, cookie);
f10dda3b 2273
992c052c 2274 bus_match_parse_free(components, n_components);
f10dda3b 2275
992c052c 2276 return r < 0 ? r : q;
f10dda3b
LP
2277}
2278
992c052c
LP
2279bool bus_pid_changed(sd_bus *bus) {
2280 assert(bus);
f10dda3b 2281
992c052c
LP
2282 /* We don't support people creating a bus connection and
2283 * keeping it around over a fork(). Let's complain. */
d5a2b9a6 2284
992c052c 2285 return bus->original_pid != getpid();
d5a2b9a6 2286}
40ca29a1
LP
2287
2288static int io_callback(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
2289 void *bus = userdata;
2290 int r;
2291
2292 assert(bus);
2293
2294 r = sd_bus_process(bus, NULL);
2295 if (r < 0)
2296 return r;
2297
2298 return 1;
2299}
2300
2301static int time_callback(sd_event_source *s, uint64_t usec, void *userdata) {
2302 void *bus = userdata;
2303 int r;
2304
2305 assert(bus);
2306
2307 r = sd_bus_process(bus, NULL);
2308 if (r < 0)
2309 return r;
2310
2311 return 1;
2312}
2313
2314static int prepare_callback(sd_event_source *s, void *userdata) {
2315 sd_bus *bus = userdata;
2316 int r, e;
2317 usec_t until;
2318
2319 assert(s);
2320 assert(bus);
2321
2322 e = sd_bus_get_events(bus);
2323 if (e < 0)
2324 return e;
2325
2326 if (bus->output_fd != bus->input_fd) {
2327
2328 r = sd_event_source_set_io_events(bus->input_io_event_source, e & POLLIN);
2329 if (r < 0)
2330 return r;
2331
2332 r = sd_event_source_set_io_events(bus->output_io_event_source, e & POLLOUT);
2333 if (r < 0)
2334 return r;
2335 } else {
2336 r = sd_event_source_set_io_events(bus->input_io_event_source, e);
2337 if (r < 0)
2338 return r;
2339 }
2340
2341 r = sd_bus_get_timeout(bus, &until);
2342 if (r < 0)
2343 return r;
2344 if (r > 0) {
2345 int j;
2346
2347 j = sd_event_source_set_time(bus->time_event_source, until);
2348 if (j < 0)
2349 return j;
2350 }
2351
2352 r = sd_event_source_set_enabled(bus->time_event_source, r > 0);
2353 if (r < 0)
2354 return r;
2355
2356 return 1;
2357}
2358
abc5fe72
LP
2359static int quit_callback(sd_event_source *event, void *userdata) {
2360 sd_bus *bus = userdata;
2361
2362 assert(event);
2363
2364 sd_bus_flush(bus);
2365
2366 return 1;
2367}
2368
d9f644e2 2369_public_ int sd_bus_attach_event(sd_bus *bus, sd_event *event, int priority) {
40ca29a1
LP
2370 int r;
2371
2372 assert_return(bus, -EINVAL);
40ca29a1
LP
2373 assert_return(!bus->event, -EBUSY);
2374
2375 assert(!bus->input_io_event_source);
2376 assert(!bus->output_io_event_source);
2377 assert(!bus->time_event_source);
2378
76b54375
LP
2379 if (event)
2380 bus->event = sd_event_ref(event);
2381 else {
2382 r = sd_event_default(&bus->event);
2383 if (r < 0)
2384 return r;
2385 }
40ca29a1 2386
76b54375 2387 r = sd_event_add_io(bus->event, bus->input_fd, 0, io_callback, bus, &bus->input_io_event_source);
40ca29a1
LP
2388 if (r < 0)
2389 goto fail;
2390
2391 r = sd_event_source_set_priority(bus->input_io_event_source, priority);
2392 if (r < 0)
2393 goto fail;
2394
2395 if (bus->output_fd != bus->input_fd) {
76b54375 2396 r = sd_event_add_io(bus->event, bus->output_fd, 0, io_callback, bus, &bus->output_io_event_source);
40ca29a1
LP
2397 if (r < 0)
2398 goto fail;
2399
2400 r = sd_event_source_set_priority(bus->output_io_event_source, priority);
2401 if (r < 0)
2402 goto fail;
2403 }
2404
2405 r = sd_event_source_set_prepare(bus->input_io_event_source, prepare_callback);
2406 if (r < 0)
2407 goto fail;
2408
76b54375 2409 r = sd_event_add_monotonic(bus->event, 0, 0, time_callback, bus, &bus->time_event_source);
40ca29a1
LP
2410 if (r < 0)
2411 goto fail;
2412
2413 r = sd_event_source_set_priority(bus->time_event_source, priority);
2414 if (r < 0)
2415 goto fail;
2416
76b54375 2417 r = sd_event_add_quit(bus->event, quit_callback, bus, &bus->quit_event_source);
abc5fe72
LP
2418 if (r < 0)
2419 goto fail;
2420
40ca29a1
LP
2421 return 0;
2422
2423fail:
2424 sd_bus_detach_event(bus);
2425 return r;
2426}
2427
d9f644e2 2428_public_ int sd_bus_detach_event(sd_bus *bus) {
40ca29a1
LP
2429 assert_return(bus, -EINVAL);
2430 assert_return(bus->event, -ENXIO);
2431
2432 if (bus->input_io_event_source)
2433 bus->input_io_event_source = sd_event_source_unref(bus->input_io_event_source);
2434
2435 if (bus->output_io_event_source)
2436 bus->output_io_event_source = sd_event_source_unref(bus->output_io_event_source);
2437
2438 if (bus->time_event_source)
2439 bus->time_event_source = sd_event_source_unref(bus->time_event_source);
2440
abc5fe72
LP
2441 if (bus->quit_event_source)
2442 bus->quit_event_source = sd_event_source_unref(bus->quit_event_source);
2443
40ca29a1
LP
2444 if (bus->event)
2445 bus->event = sd_event_unref(bus->event);
2446
2447 return 0;
2448}
affff0b6 2449
76b54375 2450_public_ sd_bus_message* sd_bus_get_current(sd_bus *bus) {
affff0b6
LP
2451 assert_return(bus, NULL);
2452
2453 return bus->current;
2454}
76b54375
LP
2455
2456static int bus_default(int (*bus_open)(sd_bus **), sd_bus **default_bus, sd_bus **ret) {
2457 sd_bus *b = NULL;
2458 int r;
2459
2460 assert(bus_open);
2461 assert(default_bus);
2462
2463 if (!ret)
2464 return !!*default_bus;
2465
2466 if (*default_bus) {
2467 *ret = sd_bus_ref(*default_bus);
2468 return 0;
2469 }
2470
2471 r = bus_open(&b);
2472 if (r < 0)
2473 return r;
2474
2475 b->default_bus_ptr = default_bus;
2476 b->tid = gettid();
2477 *default_bus = b;
2478
2479 *ret = b;
2480 return 1;
2481}
2482
2483_public_ int sd_bus_default_system(sd_bus **ret) {
2484 static __thread sd_bus *default_system_bus = NULL;
2485
2486 return bus_default(sd_bus_open_system, &default_system_bus, ret);
2487}
2488
2489_public_ int sd_bus_default_user(sd_bus **ret) {
2490 static __thread sd_bus *default_user_bus = NULL;
2491
2492 return bus_default(sd_bus_open_user, &default_user_bus, ret);
2493}
2494
2495_public_ int sd_bus_get_tid(sd_bus *b, pid_t *tid) {
2496 assert_return(b, -EINVAL);
2497 assert_return(tid, -EINVAL);
2498 assert_return(!bus_pid_changed(b), -ECHILD);
2499
2500 if (b->tid != 0) {
2501 *tid = b->tid;
2502 return 0;
2503 }
2504
2505 if (b->event)
2506 return sd_event_get_tid(b->event, tid);
2507
2508 return -ENXIO;
2509}