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