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