LCOV - code coverage report
Current view: top level - libsystemd/sd-bus - sd-bus.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 1395 2377 58.7 %
Date: 2019-08-23 13:36:53 Functions: 107 158 67.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 933 2417 38.6 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <endian.h>
       4                 :            : #include <netdb.h>
       5                 :            : #include <poll.h>
       6                 :            : #include <pthread.h>
       7                 :            : #include <signal.h>
       8                 :            : #include <stdlib.h>
       9                 :            : #include <sys/mman.h>
      10                 :            : #include <sys/wait.h>
      11                 :            : #include <unistd.h>
      12                 :            : 
      13                 :            : #include "sd-bus.h"
      14                 :            : 
      15                 :            : #include "alloc-util.h"
      16                 :            : #include "bus-container.h"
      17                 :            : #include "bus-control.h"
      18                 :            : #include "bus-internal.h"
      19                 :            : #include "bus-kernel.h"
      20                 :            : #include "bus-label.h"
      21                 :            : #include "bus-message.h"
      22                 :            : #include "bus-objects.h"
      23                 :            : #include "bus-protocol.h"
      24                 :            : #include "bus-slot.h"
      25                 :            : #include "bus-socket.h"
      26                 :            : #include "bus-track.h"
      27                 :            : #include "bus-type.h"
      28                 :            : #include "bus-util.h"
      29                 :            : #include "cgroup-util.h"
      30                 :            : #include "def.h"
      31                 :            : #include "errno-util.h"
      32                 :            : #include "fd-util.h"
      33                 :            : #include "hexdecoct.h"
      34                 :            : #include "hostname-util.h"
      35                 :            : #include "macro.h"
      36                 :            : #include "memory-util.h"
      37                 :            : #include "missing.h"
      38                 :            : #include "parse-util.h"
      39                 :            : #include "path-util.h"
      40                 :            : #include "process-util.h"
      41                 :            : #include "string-util.h"
      42                 :            : #include "strv.h"
      43                 :            : 
      44                 :            : #define log_debug_bus_message(m)                                         \
      45                 :            :         do {                                                             \
      46                 :            :                 sd_bus_message *_mm = (m);                               \
      47                 :            :                 log_debug("Got message type=%s sender=%s destination=%s path=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " signature=%s error-name=%s error-message=%s", \
      48                 :            :                           bus_message_type_to_string(_mm->header->type), \
      49                 :            :                           strna(sd_bus_message_get_sender(_mm)),         \
      50                 :            :                           strna(sd_bus_message_get_destination(_mm)),    \
      51                 :            :                           strna(sd_bus_message_get_path(_mm)),           \
      52                 :            :                           strna(sd_bus_message_get_interface(_mm)),      \
      53                 :            :                           strna(sd_bus_message_get_member(_mm)),         \
      54                 :            :                           BUS_MESSAGE_COOKIE(_mm),                       \
      55                 :            :                           _mm->reply_cookie,                             \
      56                 :            :                           strna(_mm->root_container.signature),          \
      57                 :            :                           strna(_mm->error.name),                        \
      58                 :            :                           strna(_mm->error.message));                    \
      59                 :            :         } while (false)
      60                 :            : 
      61                 :            : static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec);
      62                 :            : static void bus_detach_io_events(sd_bus *b);
      63                 :            : static void bus_detach_inotify_event(sd_bus *b);
      64                 :            : 
      65                 :            : static thread_local sd_bus *default_system_bus = NULL;
      66                 :            : static thread_local sd_bus *default_user_bus = NULL;
      67                 :            : static thread_local sd_bus *default_starter_bus = NULL;
      68                 :            : 
      69                 :          0 : static sd_bus **bus_choose_default(int (**bus_open)(sd_bus **)) {
      70                 :            :         const char *e;
      71                 :            : 
      72                 :            :         /* Let's try our best to reuse another cached connection. If
      73                 :            :          * the starter bus type is set, connect via our normal
      74                 :            :          * connection logic, ignoring $DBUS_STARTER_ADDRESS, so that
      75                 :            :          * we can share the connection with the user/system default
      76                 :            :          * bus. */
      77                 :            : 
      78                 :          0 :         e = secure_getenv("DBUS_STARTER_BUS_TYPE");
      79         [ #  # ]:          0 :         if (e) {
      80         [ #  # ]:          0 :                 if (streq(e, "system")) {
      81         [ #  # ]:          0 :                         if (bus_open)
      82                 :          0 :                                 *bus_open = sd_bus_open_system;
      83                 :          0 :                         return &default_system_bus;
      84         [ #  # ]:          0 :                 } else if (STR_IN_SET(e, "user", "session")) {
      85         [ #  # ]:          0 :                         if (bus_open)
      86                 :          0 :                                 *bus_open = sd_bus_open_user;
      87                 :          0 :                         return &default_user_bus;
      88                 :            :                 }
      89                 :            :         }
      90                 :            : 
      91                 :            :         /* No type is specified, so we have not other option than to
      92                 :            :          * use the starter address if it is set. */
      93                 :          0 :         e = secure_getenv("DBUS_STARTER_ADDRESS");
      94         [ #  # ]:          0 :         if (e) {
      95         [ #  # ]:          0 :                 if (bus_open)
      96                 :          0 :                         *bus_open = sd_bus_open;
      97                 :          0 :                 return &default_starter_bus;
      98                 :            :         }
      99                 :            : 
     100                 :            :         /* Finally, if nothing is set use the cached connection for
     101                 :            :          * the right scope */
     102                 :            : 
     103         [ #  # ]:          0 :         if (cg_pid_get_owner_uid(0, NULL) >= 0) {
     104         [ #  # ]:          0 :                 if (bus_open)
     105                 :          0 :                         *bus_open = sd_bus_open_user;
     106                 :          0 :                 return &default_user_bus;
     107                 :            :         } else {
     108         [ #  # ]:          0 :                 if (bus_open)
     109                 :          0 :                         *bus_open = sd_bus_open_system;
     110                 :          0 :                 return &default_system_bus;
     111                 :            :         }
     112                 :            : }
     113                 :            : 
     114                 :       4941 : sd_bus *bus_resolve(sd_bus *bus) {
     115   [ -  -  -  + ]:       4941 :         switch ((uintptr_t) bus) {
     116                 :          0 :         case (uintptr_t) SD_BUS_DEFAULT:
     117                 :          0 :                 return *(bus_choose_default(NULL));
     118                 :          0 :         case (uintptr_t) SD_BUS_DEFAULT_USER:
     119                 :          0 :                 return default_user_bus;
     120                 :          0 :         case (uintptr_t) SD_BUS_DEFAULT_SYSTEM:
     121                 :          0 :                 return default_system_bus;
     122                 :       4941 :         default:
     123                 :       4941 :                 return bus;
     124                 :            :         }
     125                 :            : }
     126                 :            : 
     127                 :        700 : void bus_close_io_fds(sd_bus *b) {
     128         [ -  + ]:        700 :         assert(b);
     129                 :            : 
     130                 :        700 :         bus_detach_io_events(b);
     131                 :            : 
     132         [ -  + ]:        700 :         if (b->input_fd != b->output_fd)
     133                 :          0 :                 safe_close(b->output_fd);
     134                 :        700 :         b->output_fd = b->input_fd = safe_close(b->input_fd);
     135                 :        700 : }
     136                 :            : 
     137                 :        716 : void bus_close_inotify_fd(sd_bus *b) {
     138         [ -  + ]:        716 :         assert(b);
     139                 :            : 
     140                 :        716 :         bus_detach_inotify_event(b);
     141                 :            : 
     142                 :        716 :         b->inotify_fd = safe_close(b->inotify_fd);
     143                 :        716 :         b->inotify_watches = mfree(b->inotify_watches);
     144                 :        716 :         b->n_inotify_watches = 0;
     145                 :        716 : }
     146                 :            : 
     147                 :        332 : static void bus_reset_queues(sd_bus *b) {
     148         [ -  + ]:        332 :         assert(b);
     149                 :            : 
     150         [ +  + ]:        340 :         while (b->rqueue_size > 0)
     151                 :          8 :                 bus_message_unref_queued(b->rqueue[--b->rqueue_size], b);
     152                 :            : 
     153                 :        332 :         b->rqueue = mfree(b->rqueue);
     154                 :        332 :         b->rqueue_allocated = 0;
     155                 :            : 
     156         [ +  + ]:        352 :         while (b->wqueue_size > 0)
     157                 :         20 :                 bus_message_unref_queued(b->wqueue[--b->wqueue_size], b);
     158                 :            : 
     159                 :        332 :         b->wqueue = mfree(b->wqueue);
     160                 :        332 :         b->wqueue_allocated = 0;
     161                 :        332 : }
     162                 :            : 
     163                 :        212 : static sd_bus* bus_free(sd_bus *b) {
     164                 :            :         sd_bus_slot *s;
     165                 :            : 
     166         [ -  + ]:        212 :         assert(b);
     167         [ -  + ]:        212 :         assert(!b->track_queue);
     168         [ -  + ]:        212 :         assert(!b->tracks);
     169                 :            : 
     170                 :        212 :         b->state = BUS_CLOSED;
     171                 :            : 
     172                 :        212 :         sd_bus_detach_event(b);
     173                 :            : 
     174         [ +  + ]:        445 :         while ((s = b->slots)) {
     175                 :            :                 /* At this point only floating slots can still be
     176                 :            :                  * around, because the non-floating ones keep a
     177                 :            :                  * reference to the bus, and we thus couldn't be
     178                 :            :                  * destructing right now... We forcibly disconnect the
     179                 :            :                  * slots here, so that they still can be referenced by
     180                 :            :                  * apps, but are dead. */
     181                 :            : 
     182         [ -  + ]:        233 :                 assert(s->floating);
     183                 :        233 :                 bus_slot_disconnect(s, true);
     184                 :            :         }
     185                 :            : 
     186         [ +  + ]:        212 :         if (b->default_bus_ptr)
     187                 :          4 :                 *b->default_bus_ptr = NULL;
     188                 :            : 
     189                 :        212 :         bus_close_io_fds(b);
     190                 :        212 :         bus_close_inotify_fd(b);
     191                 :            : 
     192                 :        212 :         free(b->label);
     193                 :        212 :         free(b->groups);
     194                 :        212 :         free(b->rbuffer);
     195                 :        212 :         free(b->unique_name);
     196                 :        212 :         free(b->auth_buffer);
     197                 :        212 :         free(b->address);
     198                 :        212 :         free(b->machine);
     199                 :        212 :         free(b->description);
     200                 :        212 :         free(b->patch_sender);
     201                 :            : 
     202                 :        212 :         free(b->exec_path);
     203                 :        212 :         strv_free(b->exec_argv);
     204                 :            : 
     205                 :        212 :         close_many(b->fds, b->n_fds);
     206                 :        212 :         free(b->fds);
     207                 :            : 
     208                 :        212 :         bus_reset_queues(b);
     209                 :            : 
     210                 :        212 :         ordered_hashmap_free_free(b->reply_callbacks);
     211                 :        212 :         prioq_free(b->reply_callbacks_prioq);
     212                 :            : 
     213         [ -  + ]:        212 :         assert(b->match_callbacks.type == BUS_MATCH_ROOT);
     214                 :        212 :         bus_match_free(&b->match_callbacks);
     215                 :            : 
     216                 :        212 :         hashmap_free_free(b->vtable_methods);
     217                 :        212 :         hashmap_free_free(b->vtable_properties);
     218                 :            : 
     219         [ -  + ]:        212 :         assert(hashmap_isempty(b->nodes));
     220                 :        212 :         hashmap_free(b->nodes);
     221                 :            : 
     222                 :        212 :         bus_flush_memfd(b);
     223                 :            : 
     224         [ -  + ]:        212 :         assert_se(pthread_mutex_destroy(&b->memfd_cache_mutex) == 0);
     225                 :            : 
     226                 :        212 :         return mfree(b);
     227                 :            : }
     228                 :            : 
     229         [ -  + ]:        104 : DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus*, bus_free);
     230                 :            : 
     231                 :        212 : _public_ int sd_bus_new(sd_bus **ret) {
     232                 :        212 :         _cleanup_free_ sd_bus *b = NULL;
     233                 :            : 
     234   [ -  +  -  + ]:        212 :         assert_return(ret, -EINVAL);
     235                 :            : 
     236                 :        212 :         b = new(sd_bus, 1);
     237         [ -  + ]:        212 :         if (!b)
     238                 :          0 :                 return -ENOMEM;
     239                 :            : 
     240                 :        424 :         *b = (sd_bus) {
     241                 :            :                 .n_ref = 1,
     242                 :            :                 .input_fd = -1,
     243                 :            :                 .output_fd = -1,
     244                 :            :                 .inotify_fd = -1,
     245                 :            :                 .message_version = 1,
     246                 :            :                 .creds_mask = SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME,
     247                 :            :                 .accept_fd = true,
     248                 :        212 :                 .original_pid = getpid_cached(),
     249                 :            :                 .n_groups = (size_t) -1,
     250                 :            :                 .close_on_exit = true,
     251                 :            :         };
     252                 :            : 
     253                 :            :         /* We guarantee that wqueue always has space for at least one entry */
     254         [ -  + ]:        212 :         if (!GREEDY_REALLOC(b->wqueue, b->wqueue_allocated, 1))
     255                 :          0 :                 return -ENOMEM;
     256                 :            : 
     257         [ -  + ]:        212 :         assert_se(pthread_mutex_init(&b->memfd_cache_mutex, NULL) == 0);
     258                 :            : 
     259                 :        212 :         *ret = TAKE_PTR(b);
     260                 :        212 :         return 0;
     261                 :            : }
     262                 :            : 
     263                 :        128 : _public_ int sd_bus_set_address(sd_bus *bus, const char *address) {
     264   [ -  +  -  + ]:        128 :         assert_return(bus, -EINVAL);
     265   [ -  +  -  + ]:        128 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
     266   [ -  +  -  + ]:        128 :         assert_return(bus->state == BUS_UNSET, -EPERM);
     267   [ -  +  -  + ]:        128 :         assert_return(address, -EINVAL);
     268   [ -  +  -  + ]:        128 :         assert_return(!bus_pid_changed(bus), -ECHILD);
     269                 :            : 
     270                 :        128 :         return free_and_strdup(&bus->address, address);
     271                 :            : }
     272                 :            : 
     273                 :         76 : _public_ int sd_bus_set_fd(sd_bus *bus, int input_fd, int output_fd) {
     274   [ -  +  -  + ]:         76 :         assert_return(bus, -EINVAL);
     275   [ -  +  -  + ]:         76 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
     276   [ -  +  -  + ]:         76 :         assert_return(bus->state == BUS_UNSET, -EPERM);
     277   [ -  +  -  + ]:         76 :         assert_return(input_fd >= 0, -EBADF);
     278   [ -  +  -  + ]:         76 :         assert_return(output_fd >= 0, -EBADF);
     279   [ -  +  -  + ]:         76 :         assert_return(!bus_pid_changed(bus), -ECHILD);
     280                 :            : 
     281                 :         76 :         bus->input_fd = input_fd;
     282                 :         76 :         bus->output_fd = output_fd;
     283                 :         76 :         return 0;
     284                 :            : }
     285                 :            : 
     286                 :          0 : _public_ int sd_bus_set_exec(sd_bus *bus, const char *path, char *const argv[]) {
     287                 :          0 :         _cleanup_strv_free_ char **a = NULL;
     288                 :            :         int r;
     289                 :            : 
     290   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
     291   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
     292   [ #  #  #  # ]:          0 :         assert_return(bus->state == BUS_UNSET, -EPERM);
     293   [ #  #  #  # ]:          0 :         assert_return(path, -EINVAL);
     294   [ #  #  #  # ]:          0 :         assert_return(!strv_isempty(argv), -EINVAL);
     295   [ #  #  #  # ]:          0 :         assert_return(!bus_pid_changed(bus), -ECHILD);
     296                 :            : 
     297                 :          0 :         a = strv_copy(argv);
     298         [ #  # ]:          0 :         if (!a)
     299                 :          0 :                 return -ENOMEM;
     300                 :            : 
     301                 :          0 :         r = free_and_strdup(&bus->exec_path, path);
     302         [ #  # ]:          0 :         if (r < 0)
     303                 :          0 :                 return r;
     304                 :            : 
     305                 :          0 :         return strv_free_and_replace(bus->exec_argv, a);
     306                 :            : }
     307                 :            : 
     308                 :          4 : _public_ int sd_bus_set_bus_client(sd_bus *bus, int b) {
     309   [ -  +  -  + ]:          4 :         assert_return(bus, -EINVAL);
     310   [ -  +  -  + ]:          4 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
     311   [ -  +  -  + ]:          4 :         assert_return(bus->state == BUS_UNSET, -EPERM);
     312   [ -  +  -  + ]:          4 :         assert_return(!bus->patch_sender, -EPERM);
     313   [ -  +  -  + ]:          4 :         assert_return(!bus_pid_changed(bus), -ECHILD);
     314                 :            : 
     315                 :          4 :         bus->bus_client = !!b;
     316                 :          4 :         return 0;
     317                 :            : }
     318                 :            : 
     319                 :          0 : _public_ int sd_bus_set_monitor(sd_bus *bus, int b) {
     320   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
     321   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
     322   [ #  #  #  # ]:          0 :         assert_return(bus->state == BUS_UNSET, -EPERM);
     323   [ #  #  #  # ]:          0 :         assert_return(!bus_pid_changed(bus), -ECHILD);
     324                 :            : 
     325                 :          0 :         bus->is_monitor = !!b;
     326                 :          0 :         return 0;
     327                 :            : }
     328                 :            : 
     329                 :         56 : _public_ int sd_bus_negotiate_fds(sd_bus *bus, int b) {
     330   [ -  +  -  + ]:         56 :         assert_return(bus, -EINVAL);
     331   [ -  +  -  + ]:         56 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
     332   [ -  +  -  + ]:         56 :         assert_return(bus->state == BUS_UNSET, -EPERM);
     333   [ -  +  -  + ]:         56 :         assert_return(!bus_pid_changed(bus), -ECHILD);
     334                 :            : 
     335                 :         56 :         bus->accept_fd = !!b;
     336                 :         56 :         return 0;
     337                 :            : }
     338                 :            : 
     339                 :          0 : _public_ int sd_bus_negotiate_timestamp(sd_bus *bus, int b) {
     340   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
     341   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
     342   [ #  #  #  #  :          0 :         assert_return(!IN_SET(bus->state, BUS_CLOSING, BUS_CLOSED), -EPERM);
                   #  # ]
     343   [ #  #  #  # ]:          0 :         assert_return(!bus_pid_changed(bus), -ECHILD);
     344                 :            : 
     345                 :            :         /* This is not actually supported by any of our transports these days, but we do honour it for synthetic
     346                 :            :          * replies, and maybe one day classic D-Bus learns this too */
     347                 :          0 :         bus->attach_timestamp = !!b;
     348                 :            : 
     349                 :          0 :         return 0;
     350                 :            : }
     351                 :            : 
     352                 :          4 : _public_ int sd_bus_negotiate_creds(sd_bus *bus, int b, uint64_t mask) {
     353   [ -  +  -  + ]:          4 :         assert_return(bus, -EINVAL);
     354   [ -  +  -  + ]:          4 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
     355   [ -  +  -  + ]:          4 :         assert_return(mask <= _SD_BUS_CREDS_ALL, -EINVAL);
     356   [ -  +  -  +  :          4 :         assert_return(!IN_SET(bus->state, BUS_CLOSING, BUS_CLOSED), -EPERM);
                   -  + ]
     357   [ -  +  -  + ]:          4 :         assert_return(!bus_pid_changed(bus), -ECHILD);
     358                 :            : 
     359         [ +  - ]:          4 :         SET_FLAG(bus->creds_mask, mask, b);
     360                 :            : 
     361                 :            :         /* The well knowns we need unconditionally, so that matches can work */
     362                 :          4 :         bus->creds_mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_UNIQUE_NAME;
     363                 :            : 
     364                 :          4 :         return 0;
     365                 :            : }
     366                 :            : 
     367                 :         44 : _public_ int sd_bus_set_server(sd_bus *bus, int b, sd_id128_t server_id) {
     368   [ -  +  -  + ]:         44 :         assert_return(bus, -EINVAL);
     369   [ -  +  -  + ]:         44 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
     370   [ -  +  #  #  :         44 :         assert_return(b || sd_id128_equal(server_id, SD_ID128_NULL), -EINVAL);
                   -  + ]
     371   [ -  +  -  + ]:         44 :         assert_return(bus->state == BUS_UNSET, -EPERM);
     372   [ -  +  -  + ]:         44 :         assert_return(!bus_pid_changed(bus), -ECHILD);
     373                 :            : 
     374                 :         44 :         bus->is_server = !!b;
     375                 :         44 :         bus->server_id = server_id;
     376                 :         44 :         return 0;
     377                 :            : }
     378                 :            : 
     379                 :         56 : _public_ int sd_bus_set_anonymous(sd_bus *bus, int b) {
     380   [ -  +  -  + ]:         56 :         assert_return(bus, -EINVAL);
     381   [ -  +  -  + ]:         56 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
     382   [ -  +  -  + ]:         56 :         assert_return(bus->state == BUS_UNSET, -EPERM);
     383   [ -  +  -  + ]:         56 :         assert_return(!bus_pid_changed(bus), -ECHILD);
     384                 :            : 
     385                 :         56 :         bus->anonymous_auth = !!b;
     386                 :         56 :         return 0;
     387                 :            : }
     388                 :            : 
     389                 :          4 : _public_ int sd_bus_set_trusted(sd_bus *bus, int b) {
     390   [ -  +  -  + ]:          4 :         assert_return(bus, -EINVAL);
     391   [ -  +  -  + ]:          4 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
     392   [ -  +  -  + ]:          4 :         assert_return(bus->state == BUS_UNSET, -EPERM);
     393   [ -  +  -  + ]:          4 :         assert_return(!bus_pid_changed(bus), -ECHILD);
     394                 :            : 
     395                 :          4 :         bus->trusted = !!b;
     396                 :          4 :         return 0;
     397                 :            : }
     398                 :            : 
     399                 :         84 : _public_ int sd_bus_set_description(sd_bus *bus, const char *description) {
     400   [ -  +  -  + ]:         84 :         assert_return(bus, -EINVAL);
     401   [ -  +  -  + ]:         84 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
     402   [ -  +  -  + ]:         84 :         assert_return(bus->state == BUS_UNSET, -EPERM);
     403   [ -  +  -  + ]:         84 :         assert_return(!bus_pid_changed(bus), -ECHILD);
     404                 :            : 
     405                 :         84 :         return free_and_strdup(&bus->description, description);
     406                 :            : }
     407                 :            : 
     408                 :          0 : _public_ int sd_bus_set_allow_interactive_authorization(sd_bus *bus, int b) {
     409   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
     410   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
     411   [ #  #  #  # ]:          0 :         assert_return(!bus_pid_changed(bus), -ECHILD);
     412                 :            : 
     413                 :          0 :         bus->allow_interactive_authorization = !!b;
     414                 :          0 :         return 0;
     415                 :            : }
     416                 :            : 
     417                 :          0 : _public_ int sd_bus_get_allow_interactive_authorization(sd_bus *bus) {
     418   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
     419   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
     420   [ #  #  #  # ]:          0 :         assert_return(!bus_pid_changed(bus), -ECHILD);
     421                 :            : 
     422                 :          0 :         return bus->allow_interactive_authorization;
     423                 :            : }
     424                 :            : 
     425                 :         16 : _public_ int sd_bus_set_watch_bind(sd_bus *bus, int b) {
     426   [ -  +  -  + ]:         16 :         assert_return(bus, -EINVAL);
     427   [ -  +  -  + ]:         16 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
     428   [ -  +  -  + ]:         16 :         assert_return(bus->state == BUS_UNSET, -EPERM);
     429   [ -  +  -  + ]:         16 :         assert_return(!bus_pid_changed(bus), -ECHILD);
     430                 :            : 
     431                 :         16 :         bus->watch_bind = !!b;
     432                 :         16 :         return 0;
     433                 :            : }
     434                 :            : 
     435                 :          0 : _public_ int sd_bus_get_watch_bind(sd_bus *bus) {
     436   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
     437   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
     438   [ #  #  #  # ]:          0 :         assert_return(!bus_pid_changed(bus), -ECHILD);
     439                 :            : 
     440                 :          0 :         return bus->watch_bind;
     441                 :            : }
     442                 :            : 
     443                 :          4 : _public_ int sd_bus_set_connected_signal(sd_bus *bus, int b) {
     444   [ -  +  -  + ]:          4 :         assert_return(bus, -EINVAL);
     445   [ -  +  -  + ]:          4 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
     446   [ -  +  -  + ]:          4 :         assert_return(bus->state == BUS_UNSET, -EPERM);
     447   [ -  +  -  + ]:          4 :         assert_return(!bus_pid_changed(bus), -ECHILD);
     448                 :            : 
     449                 :          4 :         bus->connected_signal = !!b;
     450                 :          4 :         return 0;
     451                 :            : }
     452                 :            : 
     453                 :          0 : _public_ int sd_bus_get_connected_signal(sd_bus *bus) {
     454   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
     455   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
     456   [ #  #  #  # ]:          0 :         assert_return(!bus_pid_changed(bus), -ECHILD);
     457                 :            : 
     458                 :          0 :         return bus->connected_signal;
     459                 :            : }
     460                 :            : 
     461                 :        176 : static int synthesize_connected_signal(sd_bus *bus) {
     462                 :        176 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
     463                 :            :         int r;
     464                 :            : 
     465         [ -  + ]:        176 :         assert(bus);
     466                 :            : 
     467                 :            :         /* If enabled, synthesizes a local "Connected" signal mirroring the local "Disconnected" signal. This is called
     468                 :            :          * whenever we fully established a connection, i.e. after the authorization phase, and after receiving the
     469                 :            :          * Hello() reply. Or in other words, whenever we enter BUS_RUNNING state.
     470                 :            :          *
     471                 :            :          * This is useful so that clients can start doing stuff whenever the connection is fully established in a way
     472                 :            :          * that works independently from whether we connected to a full bus or just a direct connection. */
     473                 :            : 
     474         [ +  + ]:        176 :         if (!bus->connected_signal)
     475                 :        172 :                 return 0;
     476                 :            : 
     477                 :          4 :         r = sd_bus_message_new_signal(
     478                 :            :                         bus,
     479                 :            :                         &m,
     480                 :            :                         "/org/freedesktop/DBus/Local",
     481                 :            :                         "org.freedesktop.DBus.Local",
     482                 :            :                         "Connected");
     483         [ -  + ]:          4 :         if (r < 0)
     484                 :          0 :                 return r;
     485                 :            : 
     486                 :          4 :         bus_message_set_sender_local(bus, m);
     487                 :          4 :         m->read_counter = ++bus->read_counter;
     488                 :            : 
     489                 :          4 :         r = bus_seal_synthetic_message(bus, m);
     490         [ -  + ]:          4 :         if (r < 0)
     491                 :          0 :                 return r;
     492                 :            : 
     493                 :          4 :         r = bus_rqueue_make_room(bus);
     494         [ -  + ]:          4 :         if (r < 0)
     495                 :          0 :                 return r;
     496                 :            : 
     497                 :            :         /* Insert at the very front */
     498                 :          4 :         memmove(bus->rqueue + 1, bus->rqueue, sizeof(sd_bus_message*) * bus->rqueue_size);
     499                 :          4 :         bus->rqueue[0] = bus_message_ref_queued(m, bus);
     500                 :          4 :         bus->rqueue_size++;
     501                 :            : 
     502                 :          4 :         return 0;
     503                 :            : }
     504                 :            : 
     505                 :        864 : void bus_set_state(sd_bus *bus, enum bus_state state) {
     506                 :            : 
     507                 :            :         static const char * const table[_BUS_STATE_MAX] = {
     508                 :            :                 [BUS_UNSET] = "UNSET",
     509                 :            :                 [BUS_WATCH_BIND] = "WATCH_BIND",
     510                 :            :                 [BUS_OPENING] = "OPENING",
     511                 :            :                 [BUS_AUTHENTICATING] = "AUTHENTICATING",
     512                 :            :                 [BUS_HELLO] = "HELLO",
     513                 :            :                 [BUS_RUNNING] = "RUNNING",
     514                 :            :                 [BUS_CLOSING] = "CLOSING",
     515                 :            :                 [BUS_CLOSED] = "CLOSED",
     516                 :            :         };
     517                 :            : 
     518         [ -  + ]:        864 :         assert(bus);
     519         [ -  + ]:        864 :         assert(state < _BUS_STATE_MAX);
     520                 :            : 
     521         [ +  + ]:        864 :         if (state == bus->state)
     522                 :         48 :                 return;
     523                 :            : 
     524         [ +  + ]:        816 :         log_debug("Bus %s: changing state %s → %s", strna(bus->description), table[bus->state], table[state]);
     525                 :        816 :         bus->state = state;
     526                 :            : }
     527                 :            : 
     528                 :         96 : static int hello_callback(sd_bus_message *reply, void *userdata, sd_bus_error *error) {
     529                 :            :         const char *s;
     530                 :            :         sd_bus *bus;
     531                 :            :         int r;
     532                 :            : 
     533         [ -  + ]:         96 :         assert(reply);
     534                 :         96 :         bus = reply->bus;
     535         [ -  + ]:         96 :         assert(bus);
     536   [ +  -  -  + ]:         96 :         assert(IN_SET(bus->state, BUS_HELLO, BUS_CLOSING));
     537                 :            : 
     538                 :         96 :         r = sd_bus_message_get_errno(reply);
     539         [ -  + ]:         96 :         if (r > 0)
     540                 :          0 :                 return -r;
     541                 :            : 
     542                 :         96 :         r = sd_bus_message_read(reply, "s", &s);
     543         [ -  + ]:         96 :         if (r < 0)
     544                 :          0 :                 return r;
     545                 :            : 
     546   [ +  -  -  + ]:         96 :         if (!service_name_is_valid(s) || s[0] != ':')
     547                 :          0 :                 return -EBADMSG;
     548                 :            : 
     549                 :         96 :         r = free_and_strdup(&bus->unique_name, s);
     550         [ -  + ]:         96 :         if (r < 0)
     551                 :          0 :                 return r;
     552                 :            : 
     553         [ +  - ]:         96 :         if (bus->state == BUS_HELLO) {
     554                 :         96 :                 bus_set_state(bus, BUS_RUNNING);
     555                 :            : 
     556                 :         96 :                 r = synthesize_connected_signal(bus);
     557         [ -  + ]:         96 :                 if (r < 0)
     558                 :          0 :                         return r;
     559                 :            :         }
     560                 :            : 
     561                 :         96 :         return 1;
     562                 :            : }
     563                 :            : 
     564                 :        204 : static int bus_send_hello(sd_bus *bus) {
     565                 :        204 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
     566                 :            :         int r;
     567                 :            : 
     568         [ -  + ]:        204 :         assert(bus);
     569                 :            : 
     570         [ +  + ]:        204 :         if (!bus->bus_client)
     571                 :         96 :                 return 0;
     572                 :            : 
     573                 :        108 :         r = sd_bus_message_new_method_call(
     574                 :            :                         bus,
     575                 :            :                         &m,
     576                 :            :                         "org.freedesktop.DBus",
     577                 :            :                         "/org/freedesktop/DBus",
     578                 :            :                         "org.freedesktop.DBus",
     579                 :            :                         "Hello");
     580         [ -  + ]:        108 :         if (r < 0)
     581                 :          0 :                 return r;
     582                 :            : 
     583                 :        108 :         return sd_bus_call_async(bus, NULL, m, hello_callback, NULL, 0);
     584                 :            : }
     585                 :            : 
     586                 :        176 : int bus_start_running(sd_bus *bus) {
     587                 :            :         struct reply_callback *c;
     588                 :            :         Iterator i;
     589                 :            :         usec_t n;
     590                 :            :         int r;
     591                 :            : 
     592         [ -  + ]:        176 :         assert(bus);
     593         [ -  + ]:        176 :         assert(bus->state < BUS_HELLO);
     594                 :            : 
     595                 :            :         /* We start all method call timeouts when we enter BUS_HELLO or BUS_RUNNING mode. At this point let's convert
     596                 :            :          * all relative to absolute timestamps. Note that we do not reshuffle the reply callback priority queue since
     597                 :            :          * adding a fixed value to all entries should not alter the internal order. */
     598                 :            : 
     599                 :        176 :         n = now(CLOCK_MONOTONIC);
     600         [ +  + ]:        332 :         ORDERED_HASHMAP_FOREACH(c, bus->reply_callbacks, i) {
     601         [ -  + ]:        156 :                 if (c->timeout_usec == 0)
     602                 :          0 :                         continue;
     603                 :            : 
     604                 :        156 :                 c->timeout_usec = usec_add(n, c->timeout_usec);
     605                 :            :         }
     606                 :            : 
     607         [ +  + ]:        176 :         if (bus->bus_client) {
     608                 :         96 :                 bus_set_state(bus, BUS_HELLO);
     609                 :         96 :                 return 1;
     610                 :            :         }
     611                 :            : 
     612                 :         80 :         bus_set_state(bus, BUS_RUNNING);
     613                 :            : 
     614                 :         80 :         r = synthesize_connected_signal(bus);
     615         [ -  + ]:         80 :         if (r < 0)
     616                 :          0 :                 return r;
     617                 :            : 
     618                 :         80 :         return 1;
     619                 :            : }
     620                 :            : 
     621                 :        256 : static int parse_address_key(const char **p, const char *key, char **value) {
     622                 :        256 :         size_t l, n = 0, allocated = 0;
     623                 :        256 :         _cleanup_free_ char *r = NULL;
     624                 :            :         const char *a;
     625                 :            : 
     626         [ -  + ]:        256 :         assert(p);
     627         [ -  + ]:        256 :         assert(*p);
     628         [ -  + ]:        256 :         assert(value);
     629                 :            : 
     630         [ +  - ]:        256 :         if (key) {
     631                 :        256 :                 l = strlen(key);
     632         [ +  + ]:        256 :                 if (strncmp(*p, key, l) != 0)
     633                 :        128 :                         return 0;
     634                 :            : 
     635         [ -  + ]:        128 :                 if ((*p)[l] != '=')
     636                 :          0 :                         return 0;
     637                 :            : 
     638         [ -  + ]:        128 :                 if (*value)
     639                 :          0 :                         return -EINVAL;
     640                 :            : 
     641                 :        128 :                 a = *p + l + 1;
     642                 :            :         } else
     643                 :          0 :                 a = *p;
     644                 :            : 
     645   [ +  +  +  + ]:       3476 :         while (!IN_SET(*a, ';', ',', 0)) {
     646                 :            :                 char c;
     647                 :            : 
     648         [ -  + ]:       3348 :                 if (*a == '%') {
     649                 :            :                         int x, y;
     650                 :            : 
     651                 :          0 :                         x = unhexchar(a[1]);
     652         [ #  # ]:          0 :                         if (x < 0)
     653                 :          0 :                                 return x;
     654                 :            : 
     655                 :          0 :                         y = unhexchar(a[2]);
     656         [ #  # ]:          0 :                         if (y < 0)
     657                 :          0 :                                 return y;
     658                 :            : 
     659                 :          0 :                         c = (char) ((x << 4) | y);
     660                 :          0 :                         a += 3;
     661                 :            :                 } else {
     662                 :       3348 :                         c = *a;
     663                 :       3348 :                         a++;
     664                 :            :                 }
     665                 :            : 
     666         [ -  + ]:       3348 :                 if (!GREEDY_REALLOC(r, allocated, n + 2))
     667                 :          0 :                         return -ENOMEM;
     668                 :            : 
     669                 :       3348 :                 r[n++] = c;
     670                 :            :         }
     671                 :            : 
     672         [ -  + ]:        128 :         if (!r) {
     673                 :          0 :                 r = strdup("");
     674         [ #  # ]:          0 :                 if (!r)
     675                 :          0 :                         return -ENOMEM;
     676                 :            :         } else
     677                 :        128 :                 r[n] = 0;
     678                 :            : 
     679         [ -  + ]:        128 :         if (*a == ',')
     680                 :          0 :                 a++;
     681                 :            : 
     682                 :        128 :         *p = a;
     683                 :            : 
     684                 :        128 :         free_and_replace(*value, r);
     685                 :            : 
     686                 :        128 :         return 1;
     687                 :            : }
     688                 :            : 
     689                 :          0 : static void skip_address_key(const char **p) {
     690         [ #  # ]:          0 :         assert(p);
     691         [ #  # ]:          0 :         assert(*p);
     692                 :            : 
     693                 :          0 :         *p += strcspn(*p, ",");
     694                 :            : 
     695         [ #  # ]:          0 :         if (**p == ',')
     696                 :          0 :                 (*p)++;
     697                 :          0 : }
     698                 :            : 
     699                 :        128 : static int parse_unix_address(sd_bus *b, const char **p, char **guid) {
     700                 :        128 :         _cleanup_free_ char *path = NULL, *abstract = NULL;
     701                 :            :         size_t l;
     702                 :            :         int r;
     703                 :            : 
     704         [ -  + ]:        128 :         assert(b);
     705         [ -  + ]:        128 :         assert(p);
     706         [ -  + ]:        128 :         assert(*p);
     707         [ -  + ]:        128 :         assert(guid);
     708                 :            : 
     709   [ +  +  +  + ]:        256 :         while (!IN_SET(**p, 0, ';')) {
     710                 :        128 :                 r = parse_address_key(p, "guid", guid);
     711         [ -  + ]:        128 :                 if (r < 0)
     712                 :          0 :                         return r;
     713         [ -  + ]:        128 :                 else if (r > 0)
     714                 :          0 :                         continue;
     715                 :            : 
     716                 :        128 :                 r = parse_address_key(p, "path", &path);
     717         [ -  + ]:        128 :                 if (r < 0)
     718                 :          0 :                         return r;
     719         [ +  - ]:        128 :                 else if (r > 0)
     720                 :        128 :                         continue;
     721                 :            : 
     722                 :          0 :                 r = parse_address_key(p, "abstract", &abstract);
     723         [ #  # ]:          0 :                 if (r < 0)
     724                 :          0 :                         return r;
     725         [ #  # ]:          0 :                 else if (r > 0)
     726                 :          0 :                         continue;
     727                 :            : 
     728                 :          0 :                 skip_address_key(p);
     729                 :            :         }
     730                 :            : 
     731   [ -  +  #  # ]:        128 :         if (!path && !abstract)
     732                 :          0 :                 return -EINVAL;
     733                 :            : 
     734   [ +  -  -  + ]:        128 :         if (path && abstract)
     735                 :          0 :                 return -EINVAL;
     736                 :            : 
     737         [ +  - ]:        128 :         if (path) {
     738                 :        128 :                 l = strlen(path);
     739         [ -  + ]:        128 :                 if (l >= sizeof(b->sockaddr.un.sun_path)) /* We insist on NUL termination */
     740                 :          0 :                         return -E2BIG;
     741                 :            : 
     742                 :        128 :                 b->sockaddr.un = (struct sockaddr_un) {
     743                 :            :                         .sun_family = AF_UNIX,
     744                 :            :                 };
     745                 :            : 
     746                 :        128 :                 memcpy(b->sockaddr.un.sun_path, path, l);
     747                 :        128 :                 b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + l + 1;
     748                 :            : 
     749                 :            :         } else {
     750         [ #  # ]:          0 :                 assert(abstract);
     751                 :            : 
     752                 :          0 :                 l = strlen(abstract);
     753         [ #  # ]:          0 :                 if (l >= sizeof(b->sockaddr.un.sun_path) - 1) /* We insist on NUL termination */
     754                 :          0 :                         return -E2BIG;
     755                 :            : 
     756                 :          0 :                 b->sockaddr.un = (struct sockaddr_un) {
     757                 :            :                         .sun_family = AF_UNIX,
     758                 :            :                 };
     759                 :            : 
     760                 :          0 :                 memcpy(b->sockaddr.un.sun_path+1, abstract, l);
     761                 :          0 :                 b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + 1 + l;
     762                 :            :         }
     763                 :            : 
     764                 :        128 :         b->is_local = true;
     765                 :            : 
     766                 :        128 :         return 0;
     767                 :            : }
     768                 :            : 
     769                 :          0 : static int parse_tcp_address(sd_bus *b, const char **p, char **guid) {
     770                 :          0 :         _cleanup_free_ char *host = NULL, *port = NULL, *family = NULL;
     771                 :            :         int r;
     772                 :          0 :         struct addrinfo *result, hints = {
     773                 :            :                 .ai_socktype = SOCK_STREAM,
     774                 :            :                 .ai_flags = AI_ADDRCONFIG,
     775                 :            :         };
     776                 :            : 
     777         [ #  # ]:          0 :         assert(b);
     778         [ #  # ]:          0 :         assert(p);
     779         [ #  # ]:          0 :         assert(*p);
     780         [ #  # ]:          0 :         assert(guid);
     781                 :            : 
     782   [ #  #  #  # ]:          0 :         while (!IN_SET(**p, 0, ';')) {
     783                 :          0 :                 r = parse_address_key(p, "guid", guid);
     784         [ #  # ]:          0 :                 if (r < 0)
     785                 :          0 :                         return r;
     786         [ #  # ]:          0 :                 else if (r > 0)
     787                 :          0 :                         continue;
     788                 :            : 
     789                 :          0 :                 r = parse_address_key(p, "host", &host);
     790         [ #  # ]:          0 :                 if (r < 0)
     791                 :          0 :                         return r;
     792         [ #  # ]:          0 :                 else if (r > 0)
     793                 :          0 :                         continue;
     794                 :            : 
     795                 :          0 :                 r = parse_address_key(p, "port", &port);
     796         [ #  # ]:          0 :                 if (r < 0)
     797                 :          0 :                         return r;
     798         [ #  # ]:          0 :                 else if (r > 0)
     799                 :          0 :                         continue;
     800                 :            : 
     801                 :          0 :                 r = parse_address_key(p, "family", &family);
     802         [ #  # ]:          0 :                 if (r < 0)
     803                 :          0 :                         return r;
     804         [ #  # ]:          0 :                 else if (r > 0)
     805                 :          0 :                         continue;
     806                 :            : 
     807                 :          0 :                 skip_address_key(p);
     808                 :            :         }
     809                 :            : 
     810   [ #  #  #  # ]:          0 :         if (!host || !port)
     811                 :          0 :                 return -EINVAL;
     812                 :            : 
     813         [ #  # ]:          0 :         if (family) {
     814         [ #  # ]:          0 :                 if (streq(family, "ipv4"))
     815                 :          0 :                         hints.ai_family = AF_INET;
     816         [ #  # ]:          0 :                 else if (streq(family, "ipv6"))
     817                 :          0 :                         hints.ai_family = AF_INET6;
     818                 :            :                 else
     819                 :          0 :                         return -EINVAL;
     820                 :            :         }
     821                 :            : 
     822                 :          0 :         r = getaddrinfo(host, port, &hints, &result);
     823         [ #  # ]:          0 :         if (r == EAI_SYSTEM)
     824                 :          0 :                 return -errno;
     825         [ #  # ]:          0 :         else if (r != 0)
     826                 :          0 :                 return -EADDRNOTAVAIL;
     827                 :            : 
     828                 :          0 :         memcpy(&b->sockaddr, result->ai_addr, result->ai_addrlen);
     829                 :          0 :         b->sockaddr_size = result->ai_addrlen;
     830                 :            : 
     831                 :          0 :         freeaddrinfo(result);
     832                 :            : 
     833                 :          0 :         b->is_local = false;
     834                 :            : 
     835                 :          0 :         return 0;
     836                 :            : }
     837                 :            : 
     838                 :          0 : static int parse_exec_address(sd_bus *b, const char **p, char **guid) {
     839                 :          0 :         char *path = NULL;
     840                 :          0 :         unsigned n_argv = 0, j;
     841                 :          0 :         char **argv = NULL;
     842                 :          0 :         size_t allocated = 0;
     843                 :            :         int r;
     844                 :            : 
     845         [ #  # ]:          0 :         assert(b);
     846         [ #  # ]:          0 :         assert(p);
     847         [ #  # ]:          0 :         assert(*p);
     848         [ #  # ]:          0 :         assert(guid);
     849                 :            : 
     850   [ #  #  #  # ]:          0 :         while (!IN_SET(**p, 0, ';')) {
     851                 :          0 :                 r = parse_address_key(p, "guid", guid);
     852         [ #  # ]:          0 :                 if (r < 0)
     853                 :          0 :                         goto fail;
     854         [ #  # ]:          0 :                 else if (r > 0)
     855                 :          0 :                         continue;
     856                 :            : 
     857                 :          0 :                 r = parse_address_key(p, "path", &path);
     858         [ #  # ]:          0 :                 if (r < 0)
     859                 :          0 :                         goto fail;
     860         [ #  # ]:          0 :                 else if (r > 0)
     861                 :          0 :                         continue;
     862                 :            : 
     863         [ #  # ]:          0 :                 if (startswith(*p, "argv")) {
     864                 :            :                         unsigned ul;
     865                 :            : 
     866                 :          0 :                         errno = 0;
     867                 :          0 :                         ul = strtoul(*p + 4, (char**) p, 10);
     868   [ #  #  #  #  :          0 :                         if (errno > 0 || **p != '=' || ul > 256) {
                   #  # ]
     869                 :          0 :                                 r = -EINVAL;
     870                 :          0 :                                 goto fail;
     871                 :            :                         }
     872                 :            : 
     873                 :          0 :                         (*p)++;
     874                 :            : 
     875         [ #  # ]:          0 :                         if (ul >= n_argv) {
     876         [ #  # ]:          0 :                                 if (!GREEDY_REALLOC0(argv, allocated, ul + 2)) {
     877                 :          0 :                                         r = -ENOMEM;
     878                 :          0 :                                         goto fail;
     879                 :            :                                 }
     880                 :            : 
     881                 :          0 :                                 n_argv = ul + 1;
     882                 :            :                         }
     883                 :            : 
     884                 :          0 :                         r = parse_address_key(p, NULL, argv + ul);
     885         [ #  # ]:          0 :                         if (r < 0)
     886                 :          0 :                                 goto fail;
     887                 :            : 
     888                 :          0 :                         continue;
     889                 :            :                 }
     890                 :            : 
     891                 :          0 :                 skip_address_key(p);
     892                 :            :         }
     893                 :            : 
     894         [ #  # ]:          0 :         if (!path) {
     895                 :          0 :                 r = -EINVAL;
     896                 :          0 :                 goto fail;
     897                 :            :         }
     898                 :            : 
     899                 :            :         /* Make sure there are no holes in the array, with the
     900                 :            :          * exception of argv[0] */
     901         [ #  # ]:          0 :         for (j = 1; j < n_argv; j++)
     902         [ #  # ]:          0 :                 if (!argv[j]) {
     903                 :          0 :                         r = -EINVAL;
     904                 :          0 :                         goto fail;
     905                 :            :                 }
     906                 :            : 
     907   [ #  #  #  # ]:          0 :         if (argv && argv[0] == NULL) {
     908                 :          0 :                 argv[0] = strdup(path);
     909         [ #  # ]:          0 :                 if (!argv[0]) {
     910                 :          0 :                         r = -ENOMEM;
     911                 :          0 :                         goto fail;
     912                 :            :                 }
     913                 :            :         }
     914                 :            : 
     915                 :          0 :         b->exec_path = path;
     916                 :          0 :         b->exec_argv = argv;
     917                 :            : 
     918                 :          0 :         b->is_local = false;
     919                 :            : 
     920                 :          0 :         return 0;
     921                 :            : 
     922                 :          0 : fail:
     923         [ #  # ]:          0 :         for (j = 0; j < n_argv; j++)
     924                 :          0 :                 free(argv[j]);
     925                 :            : 
     926                 :          0 :         free(argv);
     927                 :          0 :         free(path);
     928                 :          0 :         return r;
     929                 :            : }
     930                 :            : 
     931                 :          0 : static int parse_container_unix_address(sd_bus *b, const char **p, char **guid) {
     932                 :          0 :         _cleanup_free_ char *machine = NULL, *pid = NULL;
     933                 :            :         int r;
     934                 :            : 
     935         [ #  # ]:          0 :         assert(b);
     936         [ #  # ]:          0 :         assert(p);
     937         [ #  # ]:          0 :         assert(*p);
     938         [ #  # ]:          0 :         assert(guid);
     939                 :            : 
     940   [ #  #  #  # ]:          0 :         while (!IN_SET(**p, 0, ';')) {
     941                 :          0 :                 r = parse_address_key(p, "guid", guid);
     942         [ #  # ]:          0 :                 if (r < 0)
     943                 :          0 :                         return r;
     944         [ #  # ]:          0 :                 else if (r > 0)
     945                 :          0 :                         continue;
     946                 :            : 
     947                 :          0 :                 r = parse_address_key(p, "machine", &machine);
     948         [ #  # ]:          0 :                 if (r < 0)
     949                 :          0 :                         return r;
     950         [ #  # ]:          0 :                 else if (r > 0)
     951                 :          0 :                         continue;
     952                 :            : 
     953                 :          0 :                 r = parse_address_key(p, "pid", &pid);
     954         [ #  # ]:          0 :                 if (r < 0)
     955                 :          0 :                         return r;
     956         [ #  # ]:          0 :                 else if (r > 0)
     957                 :          0 :                         continue;
     958                 :            : 
     959                 :          0 :                 skip_address_key(p);
     960                 :            :         }
     961                 :            : 
     962         [ #  # ]:          0 :         if (!machine == !pid)
     963                 :          0 :                 return -EINVAL;
     964                 :            : 
     965         [ #  # ]:          0 :         if (machine) {
     966   [ #  #  #  # ]:          0 :                 if (!streq(machine, ".host") && !machine_name_is_valid(machine))
     967                 :          0 :                         return -EINVAL;
     968                 :            : 
     969                 :          0 :                 free_and_replace(b->machine, machine);
     970                 :            :         } else {
     971                 :          0 :                 b->machine = mfree(b->machine);
     972                 :            :         }
     973                 :            : 
     974         [ #  # ]:          0 :         if (pid) {
     975                 :          0 :                 r = parse_pid(pid, &b->nspid);
     976         [ #  # ]:          0 :                 if (r < 0)
     977                 :          0 :                         return r;
     978                 :            :         } else
     979                 :          0 :                 b->nspid = 0;
     980                 :            : 
     981                 :          0 :         b->sockaddr.un = (struct sockaddr_un) {
     982                 :            :                 .sun_family = AF_UNIX,
     983                 :            :                 /* Note that we use the old /var/run prefix here, to increase compatibility with really old containers */
     984                 :            :                 .sun_path = "/var/run/dbus/system_bus_socket",
     985                 :            :         };
     986   [ #  #  #  # ]:          0 :         b->sockaddr_size = SOCKADDR_UN_LEN(b->sockaddr.un);
     987                 :          0 :         b->is_local = false;
     988                 :            : 
     989                 :          0 :         return 0;
     990                 :            : }
     991                 :            : 
     992                 :        128 : static void bus_reset_parsed_address(sd_bus *b) {
     993         [ -  + ]:        128 :         assert(b);
     994                 :            : 
     995         [ +  - ]:        128 :         zero(b->sockaddr);
     996                 :        128 :         b->sockaddr_size = 0;
     997                 :        128 :         b->exec_argv = strv_free(b->exec_argv);
     998                 :        128 :         b->exec_path = mfree(b->exec_path);
     999                 :        128 :         b->server_id = SD_ID128_NULL;
    1000                 :        128 :         b->machine = mfree(b->machine);
    1001                 :        128 :         b->nspid = 0;
    1002                 :        128 : }
    1003                 :            : 
    1004                 :        128 : static int bus_parse_next_address(sd_bus *b) {
    1005                 :        128 :         _cleanup_free_ char *guid = NULL;
    1006                 :            :         const char *a;
    1007                 :            :         int r;
    1008                 :            : 
    1009         [ -  + ]:        128 :         assert(b);
    1010                 :            : 
    1011         [ -  + ]:        128 :         if (!b->address)
    1012                 :          0 :                 return 0;
    1013         [ -  + ]:        128 :         if (b->address[b->address_index] == 0)
    1014                 :          0 :                 return 0;
    1015                 :            : 
    1016                 :        128 :         bus_reset_parsed_address(b);
    1017                 :            : 
    1018                 :        128 :         a = b->address + b->address_index;
    1019                 :            : 
    1020         [ +  - ]:        128 :         while (*a != 0) {
    1021                 :            : 
    1022         [ -  + ]:        128 :                 if (*a == ';') {
    1023                 :          0 :                         a++;
    1024                 :          0 :                         continue;
    1025                 :            :                 }
    1026                 :            : 
    1027         [ +  - ]:        128 :                 if (startswith(a, "unix:")) {
    1028                 :        128 :                         a += 5;
    1029                 :            : 
    1030                 :        128 :                         r = parse_unix_address(b, &a, &guid);
    1031         [ -  + ]:        128 :                         if (r < 0)
    1032                 :          0 :                                 return r;
    1033                 :        128 :                         break;
    1034                 :            : 
    1035         [ #  # ]:          0 :                 } else if (startswith(a, "tcp:")) {
    1036                 :            : 
    1037                 :          0 :                         a += 4;
    1038                 :          0 :                         r = parse_tcp_address(b, &a, &guid);
    1039         [ #  # ]:          0 :                         if (r < 0)
    1040                 :          0 :                                 return r;
    1041                 :            : 
    1042                 :          0 :                         break;
    1043                 :            : 
    1044         [ #  # ]:          0 :                 } else if (startswith(a, "unixexec:")) {
    1045                 :            : 
    1046                 :          0 :                         a += 9;
    1047                 :          0 :                         r = parse_exec_address(b, &a, &guid);
    1048         [ #  # ]:          0 :                         if (r < 0)
    1049                 :          0 :                                 return r;
    1050                 :            : 
    1051                 :          0 :                         break;
    1052                 :            : 
    1053         [ #  # ]:          0 :                 } else if (startswith(a, "x-machine-unix:")) {
    1054                 :            : 
    1055                 :          0 :                         a += 15;
    1056                 :          0 :                         r = parse_container_unix_address(b, &a, &guid);
    1057         [ #  # ]:          0 :                         if (r < 0)
    1058                 :          0 :                                 return r;
    1059                 :            : 
    1060                 :          0 :                         break;
    1061                 :            :                 }
    1062                 :            : 
    1063                 :          0 :                 a = strchr(a, ';');
    1064         [ #  # ]:          0 :                 if (!a)
    1065                 :          0 :                         return 0;
    1066                 :            :         }
    1067                 :            : 
    1068         [ -  + ]:        128 :         if (guid) {
    1069                 :          0 :                 r = sd_id128_from_string(guid, &b->server_id);
    1070         [ #  # ]:          0 :                 if (r < 0)
    1071                 :          0 :                         return r;
    1072                 :            :         }
    1073                 :            : 
    1074                 :        128 :         b->address_index = a - b->address;
    1075                 :        128 :         return 1;
    1076                 :            : }
    1077                 :            : 
    1078                 :        432 : static void bus_kill_exec(sd_bus *bus) {
    1079         [ -  + ]:        432 :         if (pid_is_valid(bus->busexec_pid) > 0) {
    1080                 :          0 :                 sigterm_wait(bus->busexec_pid);
    1081                 :          0 :                 bus->busexec_pid = 0;
    1082                 :            :         }
    1083                 :        432 : }
    1084                 :            : 
    1085                 :        128 : static int bus_start_address(sd_bus *b) {
    1086                 :            :         int r;
    1087                 :            : 
    1088         [ -  + ]:        128 :         assert(b);
    1089                 :            : 
    1090                 :            :         for (;;) {
    1091                 :        256 :                 bus_close_io_fds(b);
    1092                 :        256 :                 bus_close_inotify_fd(b);
    1093                 :            : 
    1094                 :        256 :                 bus_kill_exec(b);
    1095                 :            : 
    1096                 :            :                 /* If you provide multiple different bus-addresses, we
    1097                 :            :                  * try all of them in order and use the first one that
    1098                 :            :                  * succeeds. */
    1099                 :            : 
    1100         [ -  + ]:        256 :                 if (b->exec_path)
    1101                 :          0 :                         r = bus_socket_exec(b);
    1102   [ +  -  -  +  :        256 :                 else if ((b->nspid > 0 || b->machine) && b->sockaddr.sa.sa_family != AF_UNSPEC)
                   #  # ]
    1103                 :          0 :                         r = bus_container_connect_socket(b);
    1104         [ +  + ]:        256 :                 else if (b->sockaddr.sa.sa_family != AF_UNSPEC)
    1105                 :        128 :                         r = bus_socket_connect(b);
    1106                 :            :                 else
    1107                 :        128 :                         goto next;
    1108                 :            : 
    1109         [ +  - ]:        128 :                 if (r >= 0) {
    1110                 :            :                         int q;
    1111                 :            : 
    1112                 :        128 :                         q = bus_attach_io_events(b);
    1113         [ -  + ]:        128 :                         if (q < 0)
    1114                 :          0 :                                 return q;
    1115                 :            : 
    1116                 :        128 :                         q = bus_attach_inotify_event(b);
    1117         [ -  + ]:        128 :                         if (q < 0)
    1118                 :          0 :                                 return q;
    1119                 :            : 
    1120                 :        128 :                         return r;
    1121                 :            :                 }
    1122                 :            : 
    1123                 :          0 :                 b->last_connect_error = -r;
    1124                 :            : 
    1125                 :        128 :         next:
    1126                 :        128 :                 r = bus_parse_next_address(b);
    1127         [ -  + ]:        128 :                 if (r < 0)
    1128                 :          0 :                         return r;
    1129         [ -  + ]:        128 :                 if (r == 0)
    1130         [ #  # ]:          0 :                         return b->last_connect_error > 0 ? -b->last_connect_error : -ECONNREFUSED;
    1131                 :            :         }
    1132                 :            : }
    1133                 :            : 
    1134                 :          0 : int bus_next_address(sd_bus *b) {
    1135         [ #  # ]:          0 :         assert(b);
    1136                 :            : 
    1137                 :          0 :         bus_reset_parsed_address(b);
    1138                 :          0 :         return bus_start_address(b);
    1139                 :            : }
    1140                 :            : 
    1141                 :         76 : static int bus_start_fd(sd_bus *b) {
    1142                 :            :         struct stat st;
    1143                 :            :         int r;
    1144                 :            : 
    1145         [ -  + ]:         76 :         assert(b);
    1146         [ -  + ]:         76 :         assert(b->input_fd >= 0);
    1147         [ -  + ]:         76 :         assert(b->output_fd >= 0);
    1148                 :            : 
    1149                 :         76 :         r = fd_nonblock(b->input_fd, true);
    1150         [ -  + ]:         76 :         if (r < 0)
    1151                 :          0 :                 return r;
    1152                 :            : 
    1153                 :         76 :         r = fd_cloexec(b->input_fd, true);
    1154         [ -  + ]:         76 :         if (r < 0)
    1155                 :          0 :                 return r;
    1156                 :            : 
    1157         [ -  + ]:         76 :         if (b->input_fd != b->output_fd) {
    1158                 :          0 :                 r = fd_nonblock(b->output_fd, true);
    1159         [ #  # ]:          0 :                 if (r < 0)
    1160                 :          0 :                         return r;
    1161                 :            : 
    1162                 :          0 :                 r = fd_cloexec(b->output_fd, true);
    1163         [ #  # ]:          0 :                 if (r < 0)
    1164                 :          0 :                         return r;
    1165                 :            :         }
    1166                 :            : 
    1167         [ -  + ]:         76 :         if (fstat(b->input_fd, &st) < 0)
    1168                 :          0 :                 return -errno;
    1169                 :            : 
    1170                 :         76 :         return bus_socket_take_fd(b);
    1171                 :            : }
    1172                 :            : 
    1173                 :        204 : _public_ int sd_bus_start(sd_bus *bus) {
    1174                 :            :         int r;
    1175                 :            : 
    1176   [ -  +  -  + ]:        204 :         assert_return(bus, -EINVAL);
    1177   [ -  +  -  + ]:        204 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    1178   [ -  +  -  + ]:        204 :         assert_return(bus->state == BUS_UNSET, -EPERM);
    1179   [ -  +  -  + ]:        204 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    1180                 :            : 
    1181                 :        204 :         bus_set_state(bus, BUS_OPENING);
    1182                 :            : 
    1183   [ +  +  -  + ]:        204 :         if (bus->is_server && bus->bus_client)
    1184                 :          0 :                 return -EINVAL;
    1185                 :            : 
    1186         [ +  + ]:        204 :         if (bus->input_fd >= 0)
    1187                 :         76 :                 r = bus_start_fd(bus);
    1188   [ -  +  #  #  :        128 :         else if (bus->address || bus->sockaddr.sa.sa_family != AF_UNSPEC || bus->exec_path || bus->machine)
             #  #  #  # ]
    1189                 :        128 :                 r = bus_start_address(bus);
    1190                 :            :         else
    1191                 :          0 :                 return -EINVAL;
    1192                 :            : 
    1193         [ -  + ]:        204 :         if (r < 0) {
    1194                 :          0 :                 sd_bus_close(bus);
    1195                 :          0 :                 return r;
    1196                 :            :         }
    1197                 :            : 
    1198                 :        204 :         return bus_send_hello(bus);
    1199                 :            : }
    1200                 :            : 
    1201                 :          0 : _public_ int sd_bus_open_with_description(sd_bus **ret, const char *description) {
    1202                 :            :         const char *e;
    1203                 :          0 :         _cleanup_(bus_freep) sd_bus *b = NULL;
    1204                 :            :         int r;
    1205                 :            : 
    1206   [ #  #  #  # ]:          0 :         assert_return(ret, -EINVAL);
    1207                 :            : 
    1208                 :            :         /* Let's connect to the starter bus if it is set, and
    1209                 :            :          * otherwise to the bus that is appropriate for the scope
    1210                 :            :          * we are running in */
    1211                 :            : 
    1212                 :          0 :         e = secure_getenv("DBUS_STARTER_BUS_TYPE");
    1213         [ #  # ]:          0 :         if (e) {
    1214         [ #  # ]:          0 :                 if (streq(e, "system"))
    1215                 :          0 :                         return sd_bus_open_system_with_description(ret, description);
    1216         [ #  # ]:          0 :                 else if (STR_IN_SET(e, "session", "user"))
    1217                 :          0 :                         return sd_bus_open_user_with_description(ret, description);
    1218                 :            :         }
    1219                 :            : 
    1220                 :          0 :         e = secure_getenv("DBUS_STARTER_ADDRESS");
    1221         [ #  # ]:          0 :         if (!e) {
    1222         [ #  # ]:          0 :                 if (cg_pid_get_owner_uid(0, NULL) >= 0)
    1223                 :          0 :                         return sd_bus_open_user_with_description(ret, description);
    1224                 :            :                 else
    1225                 :          0 :                         return sd_bus_open_system_with_description(ret, description);
    1226                 :            :         }
    1227                 :            : 
    1228                 :          0 :         r = sd_bus_new(&b);
    1229         [ #  # ]:          0 :         if (r < 0)
    1230                 :          0 :                 return r;
    1231                 :            : 
    1232                 :          0 :         r = sd_bus_set_address(b, e);
    1233         [ #  # ]:          0 :         if (r < 0)
    1234                 :          0 :                 return r;
    1235                 :            : 
    1236                 :          0 :         b->bus_client = true;
    1237                 :            : 
    1238                 :            :         /* We don't know whether the bus is trusted or not, so better
    1239                 :            :          * be safe, and authenticate everything */
    1240                 :          0 :         b->trusted = false;
    1241                 :          0 :         b->is_local = false;
    1242                 :          0 :         b->creds_mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_EFFECTIVE_CAPS;
    1243                 :            : 
    1244                 :          0 :         r = sd_bus_start(b);
    1245         [ #  # ]:          0 :         if (r < 0)
    1246                 :          0 :                 return r;
    1247                 :            : 
    1248                 :          0 :         *ret = TAKE_PTR(b);
    1249                 :          0 :         return 0;
    1250                 :            : }
    1251                 :            : 
    1252                 :          0 : _public_ int sd_bus_open(sd_bus **ret) {
    1253                 :          0 :         return sd_bus_open_with_description(ret, NULL);
    1254                 :            : }
    1255                 :            : 
    1256                 :         60 : int bus_set_address_system(sd_bus *b) {
    1257                 :            :         const char *e;
    1258         [ -  + ]:         60 :         assert(b);
    1259                 :            : 
    1260                 :         60 :         e = secure_getenv("DBUS_SYSTEM_BUS_ADDRESS");
    1261         [ -  + ]:         60 :         if (e)
    1262                 :          0 :                 return sd_bus_set_address(b, e);
    1263                 :            : 
    1264                 :         60 :         return sd_bus_set_address(b, DEFAULT_SYSTEM_BUS_ADDRESS);
    1265                 :            : }
    1266                 :            : 
    1267                 :         60 : _public_ int sd_bus_open_system_with_description(sd_bus **ret, const char *description) {
    1268                 :         60 :         _cleanup_(bus_freep) sd_bus *b = NULL;
    1269                 :            :         int r;
    1270                 :            : 
    1271   [ -  +  -  + ]:         60 :         assert_return(ret, -EINVAL);
    1272                 :            : 
    1273                 :         60 :         r = sd_bus_new(&b);
    1274         [ -  + ]:         60 :         if (r < 0)
    1275                 :          0 :                 return r;
    1276                 :            : 
    1277         [ +  + ]:         60 :         if (description) {
    1278                 :         52 :                 r = sd_bus_set_description(b, description);
    1279         [ -  + ]:         52 :                 if (r < 0)
    1280                 :          0 :                         return r;
    1281                 :            :         }
    1282                 :            : 
    1283                 :         60 :         r = bus_set_address_system(b);
    1284         [ -  + ]:         60 :         if (r < 0)
    1285                 :          0 :                 return r;
    1286                 :            : 
    1287                 :         60 :         b->bus_client = true;
    1288                 :         60 :         b->is_system = true;
    1289                 :            : 
    1290                 :            :         /* Let's do per-method access control on the system bus. We
    1291                 :            :          * need the caller's UID and capability set for that. */
    1292                 :         60 :         b->trusted = false;
    1293                 :         60 :         b->creds_mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_EFFECTIVE_CAPS;
    1294                 :         60 :         b->is_local = true;
    1295                 :            : 
    1296                 :         60 :         r = sd_bus_start(b);
    1297         [ -  + ]:         60 :         if (r < 0)
    1298                 :          0 :                 return r;
    1299                 :            : 
    1300                 :         60 :         *ret = TAKE_PTR(b);
    1301                 :         60 :         return 0;
    1302                 :            : }
    1303                 :            : 
    1304                 :          8 : _public_ int sd_bus_open_system(sd_bus **ret) {
    1305                 :          8 :         return sd_bus_open_system_with_description(ret, NULL);
    1306                 :            : }
    1307                 :            : 
    1308                 :         44 : int bus_set_address_user(sd_bus *b) {
    1309                 :            :         const char *e;
    1310                 :         44 :         _cleanup_free_ char *ee = NULL, *s = NULL;
    1311                 :            : 
    1312         [ -  + ]:         44 :         assert(b);
    1313                 :            : 
    1314                 :         44 :         e = secure_getenv("DBUS_SESSION_BUS_ADDRESS");
    1315         [ +  - ]:         44 :         if (e)
    1316                 :         44 :                 return sd_bus_set_address(b, e);
    1317                 :            : 
    1318                 :          0 :         e = secure_getenv("XDG_RUNTIME_DIR");
    1319         [ #  # ]:          0 :         if (!e)
    1320                 :          0 :                 return -ENOENT;
    1321                 :            : 
    1322                 :          0 :         ee = bus_address_escape(e);
    1323         [ #  # ]:          0 :         if (!ee)
    1324                 :          0 :                 return -ENOMEM;
    1325                 :            : 
    1326         [ #  # ]:          0 :         if (asprintf(&s, DEFAULT_USER_BUS_ADDRESS_FMT, ee) < 0)
    1327                 :          0 :                 return -ENOMEM;
    1328                 :            : 
    1329                 :          0 :         b->address = TAKE_PTR(s);
    1330                 :            : 
    1331                 :          0 :         return 0;
    1332                 :            : }
    1333                 :            : 
    1334                 :         44 : _public_ int sd_bus_open_user_with_description(sd_bus **ret, const char *description) {
    1335                 :         44 :         _cleanup_(bus_freep) sd_bus *b = NULL;
    1336                 :            :         int r;
    1337                 :            : 
    1338   [ -  +  -  + ]:         44 :         assert_return(ret, -EINVAL);
    1339                 :            : 
    1340                 :         44 :         r = sd_bus_new(&b);
    1341         [ -  + ]:         44 :         if (r < 0)
    1342                 :          0 :                 return r;
    1343                 :            : 
    1344         [ +  + ]:         44 :         if (description) {
    1345                 :          4 :                 r = sd_bus_set_description(b, description);
    1346         [ -  + ]:          4 :                 if (r < 0)
    1347                 :          0 :                         return r;
    1348                 :            :         }
    1349                 :            : 
    1350                 :         44 :         r = bus_set_address_user(b);
    1351         [ -  + ]:         44 :         if (r < 0)
    1352                 :          0 :                 return r;
    1353                 :            : 
    1354                 :         44 :         b->bus_client = true;
    1355                 :         44 :         b->is_user = true;
    1356                 :            : 
    1357                 :            :         /* We don't do any per-method access control on the user
    1358                 :            :          * bus. */
    1359                 :         44 :         b->trusted = true;
    1360                 :         44 :         b->is_local = true;
    1361                 :            : 
    1362                 :         44 :         r = sd_bus_start(b);
    1363         [ -  + ]:         44 :         if (r < 0)
    1364                 :          0 :                 return r;
    1365                 :            : 
    1366                 :         44 :         *ret = TAKE_PTR(b);
    1367                 :         44 :         return 0;
    1368                 :            : }
    1369                 :            : 
    1370                 :         40 : _public_ int sd_bus_open_user(sd_bus **ret) {
    1371                 :         40 :         return sd_bus_open_user_with_description(ret, NULL);
    1372                 :            : }
    1373                 :            : 
    1374                 :         52 : int bus_set_address_system_remote(sd_bus *b, const char *host) {
    1375                 :         52 :         _cleanup_free_ char *e = NULL;
    1376                 :         52 :         char *m = NULL, *c = NULL, *a, *rbracket = NULL, *p = NULL;
    1377                 :            : 
    1378         [ -  + ]:         52 :         assert(b);
    1379         [ -  + ]:         52 :         assert(host);
    1380                 :            : 
    1381                 :            :         /* Skip ":"s in ipv6 addresses */
    1382         [ +  + ]:         52 :         if (*host == '[') {
    1383                 :            :                 char *t;
    1384                 :            : 
    1385                 :          4 :                 rbracket = strchr(host, ']');
    1386         [ -  + ]:          4 :                 if (!rbracket)
    1387                 :          0 :                         return -EINVAL;
    1388                 :          4 :                 t = strndupa(host + 1, rbracket - host - 1);
    1389                 :          4 :                 e = bus_address_escape(t);
    1390         [ -  + ]:          4 :                 if (!e)
    1391                 :          0 :                         return -ENOMEM;
    1392         [ +  + ]:         48 :         } else if ((a = strchr(host, '@'))) {
    1393         [ +  + ]:         32 :                 if (*(a + 1) == '[') {
    1394         [ +  + ]:         16 :                         _cleanup_free_ char *t = NULL;
    1395                 :            : 
    1396                 :         16 :                         rbracket = strchr(a + 1, ']');
    1397         [ +  + ]:         16 :                         if (!rbracket)
    1398                 :          4 :                                 return -EINVAL;
    1399         [ +  - ]:         12 :                         t = new0(char, strlen(host));
    1400         [ -  + ]:         12 :                         if (!t)
    1401                 :          0 :                                 return -ENOMEM;
    1402                 :         12 :                         strncat(t, host, a - host + 1);
    1403                 :         12 :                         strncat(t, a + 2, rbracket - a - 2);
    1404                 :         12 :                         e = bus_address_escape(t);
    1405         [ -  + ]:         12 :                         if (!e)
    1406                 :          0 :                                 return -ENOMEM;
    1407   [ +  +  +  + ]:         16 :                 } else if (*(a + 1) == '\0' || strchr(a + 1, '@'))
    1408                 :         12 :                         return -EINVAL;
    1409                 :            :         }
    1410                 :            : 
    1411                 :            :         /* Let's see if a port was given */
    1412         [ +  + ]:         36 :         m = strchr(rbracket ? rbracket + 1 : host, ':');
    1413         [ +  + ]:         36 :         if (m) {
    1414                 :            :                 char *t;
    1415                 :         20 :                 bool got_forward_slash = false;
    1416                 :            : 
    1417                 :         20 :                 p = m + 1;
    1418                 :            : 
    1419                 :         20 :                 t = strchr(p, '/');
    1420         [ -  + ]:         20 :                 if (t) {
    1421                 :          0 :                         p = strndupa(p, t - p);
    1422                 :          0 :                         got_forward_slash = true;
    1423                 :            :                 }
    1424                 :            : 
    1425   [ +  +  +  + ]:         20 :                 if (!in_charset(p, "0123456789") || *p == '\0') {
    1426   [ -  +  #  # ]:         12 :                         if (!machine_name_is_valid(p) || got_forward_slash)
    1427                 :         12 :                                 return -EINVAL;
    1428                 :            : 
    1429                 :          0 :                         m = TAKE_PTR(p);
    1430                 :          0 :                         goto interpret_port_as_machine_old_syntax;
    1431                 :            :                 }
    1432                 :            :         }
    1433                 :            : 
    1434                 :            :         /* Let's see if a machine was given */
    1435         [ +  + ]:         24 :         m = strchr(rbracket ? rbracket + 1 : host, '/');
    1436         [ -  + ]:         24 :         if (m) {
    1437                 :          0 :                 m++;
    1438                 :          0 : interpret_port_as_machine_old_syntax:
    1439                 :            :                 /* Let's make sure this is not a port of some kind,
    1440                 :            :                  * and is a valid machine name. */
    1441   [ #  #  #  # ]:          0 :                 if (!in_charset(m, "0123456789") && machine_name_is_valid(m))
    1442   [ #  #  #  #  :          0 :                         c = strjoina(",argv", p ? "7" : "5", "=--machine=", m);
          #  #  #  #  #  
             #  #  #  #  
                      # ]
    1443                 :            :         }
    1444                 :            : 
    1445         [ +  + ]:         24 :         if (!e) {
    1446                 :            :                 char *t;
    1447                 :            : 
    1448                 :         12 :                 t = strndupa(host, strcspn(host, ":/"));
    1449                 :            : 
    1450                 :         12 :                 e = bus_address_escape(t);
    1451         [ -  + ]:         12 :                 if (!e)
    1452                 :          0 :                         return -ENOMEM;
    1453                 :            :         }
    1454                 :            : 
    1455   [ +  +  +  +  :         24 :         a = strjoin("unixexec:path=ssh,argv1=-xT", p ? ",argv2=-p,argv3=" : "", strempty(p),
             +  +  +  + ]
    1456                 :            :                                 ",argv", p ? "4" : "2", "=--,argv", p ? "5" : "3", "=", e,
    1457                 :            :                                 ",argv", p ? "6" : "4", "=systemd-stdio-bridge", c);
    1458         [ -  + ]:         24 :         if (!a)
    1459                 :          0 :                 return -ENOMEM;
    1460                 :            : 
    1461                 :         24 :         return free_and_replace(b->address, a);
    1462                 :            : }
    1463                 :            : 
    1464                 :          0 : _public_ int sd_bus_open_system_remote(sd_bus **ret, const char *host) {
    1465                 :          0 :         _cleanup_(bus_freep) sd_bus *b = NULL;
    1466                 :            :         int r;
    1467                 :            : 
    1468   [ #  #  #  # ]:          0 :         assert_return(host, -EINVAL);
    1469   [ #  #  #  # ]:          0 :         assert_return(ret, -EINVAL);
    1470                 :            : 
    1471                 :          0 :         r = sd_bus_new(&b);
    1472         [ #  # ]:          0 :         if (r < 0)
    1473                 :          0 :                 return r;
    1474                 :            : 
    1475                 :          0 :         r = bus_set_address_system_remote(b, host);
    1476         [ #  # ]:          0 :         if (r < 0)
    1477                 :          0 :                 return r;
    1478                 :            : 
    1479                 :          0 :         b->bus_client = true;
    1480                 :          0 :         b->trusted = false;
    1481                 :          0 :         b->is_system = true;
    1482                 :          0 :         b->is_local = false;
    1483                 :            : 
    1484                 :          0 :         r = sd_bus_start(b);
    1485         [ #  # ]:          0 :         if (r < 0)
    1486                 :          0 :                 return r;
    1487                 :            : 
    1488                 :          0 :         *ret = TAKE_PTR(b);
    1489                 :          0 :         return 0;
    1490                 :            : }
    1491                 :            : 
    1492                 :          0 : int bus_set_address_system_machine(sd_bus *b, const char *machine) {
    1493                 :          0 :         _cleanup_free_ char *e = NULL;
    1494                 :            :         char *a;
    1495                 :            : 
    1496         [ #  # ]:          0 :         assert(b);
    1497         [ #  # ]:          0 :         assert(machine);
    1498                 :            : 
    1499                 :          0 :         e = bus_address_escape(machine);
    1500         [ #  # ]:          0 :         if (!e)
    1501                 :          0 :                 return -ENOMEM;
    1502                 :            : 
    1503                 :          0 :         a = strjoin("x-machine-unix:machine=", e);
    1504         [ #  # ]:          0 :         if (!a)
    1505                 :          0 :                 return -ENOMEM;
    1506                 :            : 
    1507                 :          0 :         return free_and_replace(b->address, a);
    1508                 :            : }
    1509                 :            : 
    1510                 :          0 : _public_ int sd_bus_open_system_machine(sd_bus **ret, const char *machine) {
    1511                 :          0 :         _cleanup_(bus_freep) sd_bus *b = NULL;
    1512                 :            :         int r;
    1513                 :            : 
    1514   [ #  #  #  # ]:          0 :         assert_return(machine, -EINVAL);
    1515   [ #  #  #  # ]:          0 :         assert_return(ret, -EINVAL);
    1516   [ #  #  #  #  :          0 :         assert_return(streq(machine, ".host") || machine_name_is_valid(machine), -EINVAL);
                   #  # ]
    1517                 :            : 
    1518                 :          0 :         r = sd_bus_new(&b);
    1519         [ #  # ]:          0 :         if (r < 0)
    1520                 :          0 :                 return r;
    1521                 :            : 
    1522                 :          0 :         r = bus_set_address_system_machine(b, machine);
    1523         [ #  # ]:          0 :         if (r < 0)
    1524                 :          0 :                 return r;
    1525                 :            : 
    1526                 :          0 :         b->bus_client = true;
    1527                 :          0 :         b->trusted = false;
    1528                 :          0 :         b->is_system = true;
    1529                 :          0 :         b->is_local = false;
    1530                 :            : 
    1531                 :          0 :         r = sd_bus_start(b);
    1532         [ #  # ]:          0 :         if (r < 0)
    1533                 :          0 :                 return r;
    1534                 :            : 
    1535                 :          0 :         *ret = TAKE_PTR(b);
    1536                 :          0 :         return 0;
    1537                 :            : }
    1538                 :            : 
    1539                 :        136 : _public_ void sd_bus_close(sd_bus *bus) {
    1540         [ -  + ]:        136 :         if (!bus)
    1541                 :          0 :                 return;
    1542         [ +  + ]:        136 :         if (bus->state == BUS_CLOSED)
    1543                 :         16 :                 return;
    1544         [ -  + ]:        120 :         if (bus_pid_changed(bus))
    1545                 :          0 :                 return;
    1546                 :            : 
    1547                 :            :         /* Don't leave ssh hanging around */
    1548                 :        120 :         bus_kill_exec(bus);
    1549                 :            : 
    1550                 :        120 :         bus_set_state(bus, BUS_CLOSED);
    1551                 :            : 
    1552                 :        120 :         sd_bus_detach_event(bus);
    1553                 :            : 
    1554                 :            :         /* Drop all queued messages so that they drop references to
    1555                 :            :          * the bus object and the bus may be freed */
    1556                 :        120 :         bus_reset_queues(bus);
    1557                 :            : 
    1558                 :        120 :         bus_close_io_fds(bus);
    1559                 :        120 :         bus_close_inotify_fd(bus);
    1560                 :            : }
    1561                 :            : 
    1562                 :        108 : _public_ sd_bus *sd_bus_close_unref(sd_bus *bus) {
    1563         [ -  + ]:        108 :         if (!bus)
    1564                 :          0 :                 return NULL;
    1565                 :            : 
    1566                 :        108 :         sd_bus_close(bus);
    1567                 :            : 
    1568                 :        108 :         return sd_bus_unref(bus);
    1569                 :            : }
    1570                 :            : 
    1571                 :         96 : _public_ sd_bus* sd_bus_flush_close_unref(sd_bus *bus) {
    1572         [ +  + ]:         96 :         if (!bus)
    1573                 :         40 :                 return NULL;
    1574                 :            : 
    1575                 :            :         /* Have to do this before flush() to prevent hang */
    1576                 :         56 :         bus_kill_exec(bus);
    1577                 :         56 :         sd_bus_flush(bus);
    1578                 :            : 
    1579                 :         56 :         return sd_bus_close_unref(bus);
    1580                 :            : }
    1581                 :            : 
    1582                 :          8 : void bus_enter_closing(sd_bus *bus) {
    1583         [ -  + ]:          8 :         assert(bus);
    1584                 :            : 
    1585   [ +  -  -  + ]:          8 :         if (!IN_SET(bus->state, BUS_WATCH_BIND, BUS_OPENING, BUS_AUTHENTICATING, BUS_HELLO, BUS_RUNNING))
    1586                 :          0 :                 return;
    1587                 :            : 
    1588                 :          8 :         bus_set_state(bus, BUS_CLOSING);
    1589                 :            : }
    1590                 :            : 
    1591   [ -  +  -  +  :       7840 : DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_bus, sd_bus, bus_free);
                   +  + ]
    1592                 :            : 
    1593                 :          0 : _public_ int sd_bus_is_open(sd_bus *bus) {
    1594   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
    1595   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    1596   [ #  #  #  # ]:          0 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    1597                 :            : 
    1598                 :          0 :         return BUS_IS_OPEN(bus->state);
    1599                 :            : }
    1600                 :            : 
    1601                 :          0 : _public_ int sd_bus_is_ready(sd_bus *bus) {
    1602   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
    1603   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    1604   [ #  #  #  # ]:          0 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    1605                 :            : 
    1606                 :          0 :         return bus->state == BUS_RUNNING;
    1607                 :            : }
    1608                 :            : 
    1609                 :         32 : _public_ int sd_bus_can_send(sd_bus *bus, char type) {
    1610                 :            :         int r;
    1611                 :            : 
    1612   [ -  +  -  + ]:         32 :         assert_return(bus, -EINVAL);
    1613   [ -  +  -  + ]:         32 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    1614   [ -  +  -  + ]:         32 :         assert_return(bus->state != BUS_UNSET, -ENOTCONN);
    1615   [ -  +  -  + ]:         32 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    1616                 :            : 
    1617         [ -  + ]:         32 :         if (bus->is_monitor)
    1618                 :          0 :                 return 0;
    1619                 :            : 
    1620         [ +  - ]:         32 :         if (type == SD_BUS_TYPE_UNIX_FD) {
    1621         [ +  + ]:         32 :                 if (!bus->accept_fd)
    1622                 :          8 :                         return 0;
    1623                 :            : 
    1624                 :         24 :                 r = bus_ensure_running(bus);
    1625         [ -  + ]:         24 :                 if (r < 0)
    1626                 :          0 :                         return r;
    1627                 :            : 
    1628                 :         24 :                 return bus->can_fds;
    1629                 :            :         }
    1630                 :            : 
    1631                 :          0 :         return bus_type_is_valid(type);
    1632                 :            : }
    1633                 :            : 
    1634                 :          4 : _public_ int sd_bus_get_bus_id(sd_bus *bus, sd_id128_t *id) {
    1635                 :            :         int r;
    1636                 :            : 
    1637   [ -  +  -  + ]:          4 :         assert_return(bus, -EINVAL);
    1638   [ -  +  -  + ]:          4 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    1639   [ -  +  -  + ]:          4 :         assert_return(id, -EINVAL);
    1640   [ -  +  -  + ]:          4 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    1641                 :            : 
    1642                 :          4 :         r = bus_ensure_running(bus);
    1643         [ -  + ]:          4 :         if (r < 0)
    1644                 :          0 :                 return r;
    1645                 :            : 
    1646                 :          4 :         *id = bus->server_id;
    1647                 :          4 :         return 0;
    1648                 :            : }
    1649                 :            : 
    1650                 :            : #define COOKIE_CYCLED (UINT32_C(1) << 31)
    1651                 :            : 
    1652                 :        560 : static uint64_t cookie_inc(uint64_t cookie) {
    1653                 :            : 
    1654                 :            :         /* Stay within the 32bit range, since classic D-Bus can't deal with more */
    1655         [ -  + ]:        560 :         if (cookie >= UINT32_MAX)
    1656                 :          0 :                 return COOKIE_CYCLED; /* Don't go back to zero, but use the highest bit for checking
    1657                 :            :                                        * whether we are looping. */
    1658                 :            : 
    1659                 :        560 :         return cookie + 1;
    1660                 :            : }
    1661                 :            : 
    1662                 :        560 : static int next_cookie(sd_bus *b) {
    1663                 :            :         uint64_t new_cookie;
    1664                 :            : 
    1665         [ -  + ]:        560 :         assert(b);
    1666                 :            : 
    1667                 :        560 :         new_cookie = cookie_inc(b->cookie);
    1668                 :            : 
    1669                 :            :         /* Small optimization: don't bother with checking for cookie reuse until we overran cookiespace at
    1670                 :            :          * least once, but then do it thorougly. */
    1671         [ -  + ]:        560 :         if (FLAGS_SET(new_cookie, COOKIE_CYCLED)) {
    1672                 :            :                 uint32_t i;
    1673                 :            : 
    1674                 :            :                 /* Check if the cookie is currently in use. If so, pick the next one */
    1675         [ #  # ]:          0 :                 for (i = 0; i < COOKIE_CYCLED; i++) {
    1676         [ #  # ]:          0 :                         if (!ordered_hashmap_contains(b->reply_callbacks, &new_cookie))
    1677                 :          0 :                                 goto good;
    1678                 :            : 
    1679                 :          0 :                         new_cookie = cookie_inc(new_cookie);
    1680                 :            :                 }
    1681                 :            : 
    1682                 :            :                 /* Can't fulfill request */
    1683                 :          0 :                 return -EBUSY;
    1684                 :            :         }
    1685                 :            : 
    1686                 :        560 : good:
    1687                 :        560 :         b->cookie = new_cookie;
    1688                 :        560 :         return 0;
    1689                 :            : }
    1690                 :            : 
    1691                 :        912 : static int bus_seal_message(sd_bus *b, sd_bus_message *m, usec_t timeout) {
    1692                 :            :         int r;
    1693                 :            : 
    1694         [ -  + ]:        912 :         assert(b);
    1695         [ -  + ]:        912 :         assert(m);
    1696                 :            : 
    1697         [ +  + ]:        912 :         if (m->sealed) {
    1698                 :            :                 /* If we copy the same message to multiple
    1699                 :            :                  * destinations, avoid using the same cookie
    1700                 :            :                  * numbers. */
    1701                 :        352 :                 b->cookie = MAX(b->cookie, BUS_MESSAGE_COOKIE(m));
    1702                 :        352 :                 return 0;
    1703                 :            :         }
    1704                 :            : 
    1705         [ +  + ]:        560 :         if (timeout == 0) {
    1706                 :        552 :                 r = sd_bus_get_method_call_timeout(b, &timeout);
    1707         [ -  + ]:        552 :                 if (r < 0)
    1708                 :          0 :                         return r;
    1709                 :            :         }
    1710                 :            : 
    1711   [ +  -  -  + ]:        560 :         if (!m->sender && b->patch_sender) {
    1712                 :          0 :                 r = sd_bus_message_set_sender(m, b->patch_sender);
    1713         [ #  # ]:          0 :                 if (r < 0)
    1714                 :          0 :                         return r;
    1715                 :            :         }
    1716                 :            : 
    1717                 :        560 :         r = next_cookie(b);
    1718         [ -  + ]:        560 :         if (r < 0)
    1719                 :          0 :                 return r;
    1720                 :            : 
    1721                 :        560 :         return sd_bus_message_seal(m, b->cookie, timeout);
    1722                 :            : }
    1723                 :            : 
    1724                 :        908 : static int bus_remarshal_message(sd_bus *b, sd_bus_message **m) {
    1725                 :        908 :         bool remarshal = false;
    1726                 :            : 
    1727         [ -  + ]:        908 :         assert(b);
    1728                 :            : 
    1729                 :            :         /* wrong packet version */
    1730   [ +  -  -  + ]:        908 :         if (b->message_version != 0 && b->message_version != (*m)->header->version)
    1731                 :          0 :                 remarshal = true;
    1732                 :            : 
    1733                 :            :         /* wrong packet endianness */
    1734   [ -  +  #  # ]:        908 :         if (b->message_endian != 0 && b->message_endian != (*m)->header->endian)
    1735                 :          0 :                 remarshal = true;
    1736                 :            : 
    1737         [ -  + ]:        908 :         return remarshal ? bus_message_remarshal(b, m) : 0;
    1738                 :            : }
    1739                 :            : 
    1740                 :         12 : int bus_seal_synthetic_message(sd_bus *b, sd_bus_message *m) {
    1741         [ -  + ]:         12 :         assert(b);
    1742         [ -  + ]:         12 :         assert(m);
    1743                 :            : 
    1744                 :            :         /* Fake some timestamps, if they were requested, and not
    1745                 :            :          * already initialized */
    1746         [ -  + ]:         12 :         if (b->attach_timestamp) {
    1747         [ #  # ]:          0 :                 if (m->realtime <= 0)
    1748                 :          0 :                         m->realtime = now(CLOCK_REALTIME);
    1749                 :            : 
    1750         [ #  # ]:          0 :                 if (m->monotonic <= 0)
    1751                 :          0 :                         m->monotonic = now(CLOCK_MONOTONIC);
    1752                 :            :         }
    1753                 :            : 
    1754                 :            :         /* The bus specification says the serial number cannot be 0,
    1755                 :            :          * hence let's fill something in for synthetic messages. Since
    1756                 :            :          * synthetic messages might have a fake sender and we don't
    1757                 :            :          * want to interfere with the real sender's serial numbers we
    1758                 :            :          * pick a fixed, artificial one. We use (uint32_t) -1 rather
    1759                 :            :          * than (uint64_t) -1 since dbus1 only had 32bit identifiers,
    1760                 :            :          * even though kdbus can do 64bit. */
    1761                 :         12 :         return sd_bus_message_seal(m, 0xFFFFFFFFULL, 0);
    1762                 :            : }
    1763                 :            : 
    1764                 :        536 : static int bus_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
    1765                 :            :         int r;
    1766                 :            : 
    1767         [ -  + ]:        536 :         assert(bus);
    1768         [ -  + ]:        536 :         assert(m);
    1769                 :            : 
    1770                 :        536 :         r = bus_socket_write_message(bus, m, idx);
    1771         [ -  + ]:        536 :         if (r <= 0)
    1772                 :          0 :                 return r;
    1773                 :            : 
    1774         [ +  - ]:        536 :         if (*idx >= BUS_MESSAGE_SIZE(m))
    1775         [ +  + ]:        536 :                 log_debug("Sent message type=%s sender=%s destination=%s path=%s interface=%s member=%s cookie=%" PRIu64 " reply_cookie=%" PRIu64 " signature=%s error-name=%s error-message=%s",
    1776                 :            :                           bus_message_type_to_string(m->header->type),
    1777                 :            :                           strna(sd_bus_message_get_sender(m)),
    1778                 :            :                           strna(sd_bus_message_get_destination(m)),
    1779                 :            :                           strna(sd_bus_message_get_path(m)),
    1780                 :            :                           strna(sd_bus_message_get_interface(m)),
    1781                 :            :                           strna(sd_bus_message_get_member(m)),
    1782                 :            :                           BUS_MESSAGE_COOKIE(m),
    1783                 :            :                           m->reply_cookie,
    1784                 :            :                           strna(m->root_container.signature),
    1785                 :            :                           strna(m->error.name),
    1786                 :            :                           strna(m->error.message));
    1787                 :            : 
    1788                 :        536 :         return r;
    1789                 :            : }
    1790                 :            : 
    1791                 :        827 : static int dispatch_wqueue(sd_bus *bus) {
    1792                 :        827 :         int r, ret = 0;
    1793                 :            : 
    1794         [ -  + ]:        827 :         assert(bus);
    1795   [ +  -  -  + ]:        827 :         assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO));
    1796                 :            : 
    1797         [ +  + ]:        995 :         while (bus->wqueue_size > 0) {
    1798                 :            : 
    1799                 :        168 :                 r = bus_write_message(bus, bus->wqueue[0], &bus->windex);
    1800         [ -  + ]:        168 :                 if (r < 0)
    1801                 :          0 :                         return r;
    1802         [ -  + ]:        168 :                 else if (r == 0)
    1803                 :            :                         /* Didn't do anything this time */
    1804                 :          0 :                         return ret;
    1805         [ +  - ]:        168 :                 else if (bus->windex >= BUS_MESSAGE_SIZE(bus->wqueue[0])) {
    1806                 :            :                         /* Fully written. Let's drop the entry from
    1807                 :            :                          * the queue.
    1808                 :            :                          *
    1809                 :            :                          * This isn't particularly optimized, but
    1810                 :            :                          * well, this is supposed to be our worst-case
    1811                 :            :                          * buffer only, and the socket buffer is
    1812                 :            :                          * supposed to be our primary buffer, and if
    1813                 :            :                          * it got full, then all bets are off
    1814                 :            :                          * anyway. */
    1815                 :            : 
    1816                 :        168 :                         bus->wqueue_size--;
    1817                 :        168 :                         bus_message_unref_queued(bus->wqueue[0], bus);
    1818                 :        168 :                         memmove(bus->wqueue, bus->wqueue + 1, sizeof(sd_bus_message*) * bus->wqueue_size);
    1819                 :        168 :                         bus->windex = 0;
    1820                 :            : 
    1821                 :        168 :                         ret = 1;
    1822                 :            :                 }
    1823                 :            :         }
    1824                 :            : 
    1825                 :        827 :         return ret;
    1826                 :            : }
    1827                 :            : 
    1828                 :       1341 : static int bus_read_message(sd_bus *bus, bool hint_priority, int64_t priority) {
    1829         [ -  + ]:       1341 :         assert(bus);
    1830                 :            : 
    1831                 :       1341 :         return bus_socket_read_message(bus);
    1832                 :            : }
    1833                 :            : 
    1834                 :        530 : int bus_rqueue_make_room(sd_bus *bus) {
    1835         [ -  + ]:        530 :         assert(bus);
    1836                 :            : 
    1837         [ -  + ]:        530 :         if (bus->rqueue_size >= BUS_RQUEUE_MAX)
    1838                 :          0 :                 return -ENOBUFS;
    1839                 :            : 
    1840         [ -  + ]:        530 :         if (!GREEDY_REALLOC(bus->rqueue, bus->rqueue_allocated, bus->rqueue_size + 1))
    1841                 :          0 :                 return -ENOMEM;
    1842                 :            : 
    1843                 :        530 :         return 0;
    1844                 :            : }
    1845                 :            : 
    1846                 :        522 : static void rqueue_drop_one(sd_bus *bus, size_t i) {
    1847         [ -  + ]:        522 :         assert(bus);
    1848         [ -  + ]:        522 :         assert(i < bus->rqueue_size);
    1849                 :            : 
    1850                 :        522 :         bus_message_unref_queued(bus->rqueue[i], bus);
    1851                 :        522 :         memmove(bus->rqueue + i, bus->rqueue + i + 1, sizeof(sd_bus_message*) * (bus->rqueue_size - i - 1));
    1852                 :        522 :         bus->rqueue_size--;
    1853                 :        522 : }
    1854                 :            : 
    1855                 :        563 : static int dispatch_rqueue(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **m) {
    1856                 :        563 :         int r, ret = 0;
    1857                 :            : 
    1858         [ -  + ]:        563 :         assert(bus);
    1859         [ -  + ]:        563 :         assert(m);
    1860   [ +  -  -  + ]:        563 :         assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO));
    1861                 :            : 
    1862                 :            :         /* Note that the priority logic is only available on kdbus,
    1863                 :            :          * where the rqueue is unused. We check the rqueue here
    1864                 :            :          * anyway, because it's simple... */
    1865                 :            : 
    1866                 :            :         for (;;) {
    1867         [ +  + ]:       1179 :                 if (bus->rqueue_size > 0) {
    1868                 :            :                         /* Dispatch a queued message */
    1869                 :        358 :                         *m = sd_bus_message_ref(bus->rqueue[0]);
    1870                 :        358 :                         rqueue_drop_one(bus, 0);
    1871                 :        358 :                         return 1;
    1872                 :            :                 }
    1873                 :            : 
    1874                 :            :                 /* Try to read a new message */
    1875                 :        821 :                 r = bus_read_message(bus, hint_priority, priority);
    1876         [ +  + ]:        821 :                 if (r < 0)
    1877                 :          4 :                         return r;
    1878         [ +  + ]:        817 :                 if (r == 0) {
    1879                 :        201 :                         *m = NULL;
    1880                 :        201 :                         return ret;
    1881                 :            :                 }
    1882                 :            : 
    1883                 :        616 :                 ret = 1;
    1884                 :            :         }
    1885                 :            : }
    1886                 :            : 
    1887                 :        560 : _public_ int sd_bus_send(sd_bus *bus, sd_bus_message *_m, uint64_t *cookie) {
    1888                 :       1120 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = sd_bus_message_ref(_m);
    1889                 :            :         int r;
    1890                 :            : 
    1891   [ -  +  -  + ]:        560 :         assert_return(m, -EINVAL);
    1892                 :            : 
    1893         [ -  + ]:        560 :         if (!bus)
    1894                 :          0 :                 bus = m->bus;
    1895                 :            : 
    1896   [ -  +  -  + ]:        560 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    1897                 :            : 
    1898         [ -  + ]:        560 :         if (!BUS_IS_OPEN(bus->state))
    1899                 :          0 :                 return -ENOTCONN;
    1900                 :            : 
    1901         [ +  + ]:        560 :         if (m->n_fds > 0) {
    1902                 :          4 :                 r = sd_bus_can_send(bus, SD_BUS_TYPE_UNIX_FD);
    1903         [ -  + ]:          4 :                 if (r < 0)
    1904                 :          0 :                         return r;
    1905         [ -  + ]:          4 :                 if (r == 0)
    1906                 :          0 :                         return -EOPNOTSUPP;
    1907                 :            :         }
    1908                 :            : 
    1909                 :            :         /* If the cookie number isn't kept, then we know that no reply
    1910                 :            :          * is expected */
    1911   [ +  +  +  + ]:        560 :         if (!cookie && !m->sealed)
    1912                 :        208 :                 m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
    1913                 :            : 
    1914                 :        560 :         r = bus_seal_message(bus, m, 0);
    1915         [ +  + ]:        560 :         if (r < 0)
    1916                 :          4 :                 return r;
    1917                 :            : 
    1918                 :            :         /* Remarshall if we have to. This will possibly unref the
    1919                 :            :          * message and place a replacement in m */
    1920                 :        556 :         r = bus_remarshal_message(bus, &m);
    1921         [ -  + ]:        556 :         if (r < 0)
    1922                 :          0 :                 return r;
    1923                 :            : 
    1924                 :            :         /* If this is a reply and no reply was requested, then let's
    1925                 :            :          * suppress this, if we can */
    1926         [ -  + ]:        556 :         if (m->dont_send)
    1927                 :          0 :                 goto finish;
    1928                 :            : 
    1929   [ +  +  +  +  :        924 :         if (IN_SET(bus->state, BUS_RUNNING, BUS_HELLO) && bus->wqueue_size <= 0) {
                   +  - ]
    1930                 :        368 :                 size_t idx = 0;
    1931                 :            : 
    1932                 :        368 :                 r = bus_write_message(bus, m, &idx);
    1933         [ -  + ]:        368 :                 if (r < 0) {
    1934         [ #  # ]:          0 :                         if (ERRNO_IS_DISCONNECT(r)) {
    1935                 :          0 :                                 bus_enter_closing(bus);
    1936                 :          0 :                                 return -ECONNRESET;
    1937                 :            :                         }
    1938                 :            : 
    1939                 :          0 :                         return r;
    1940                 :            :                 }
    1941                 :            : 
    1942         [ -  + ]:        368 :                 if (idx < BUS_MESSAGE_SIZE(m))  {
    1943                 :            :                         /* Wasn't fully written. So let's remember how
    1944                 :            :                          * much was written. Note that the first entry
    1945                 :            :                          * of the wqueue array is always allocated so
    1946                 :            :                          * that we always can remember how much was
    1947                 :            :                          * written. */
    1948                 :          0 :                         bus->wqueue[0] = bus_message_ref_queued(m, bus);
    1949                 :          0 :                         bus->wqueue_size = 1;
    1950                 :          0 :                         bus->windex = idx;
    1951                 :            :                 }
    1952                 :            : 
    1953                 :            :         } else {
    1954                 :            :                 /* Just append it to the queue. */
    1955                 :            : 
    1956         [ -  + ]:        188 :                 if (bus->wqueue_size >= BUS_WQUEUE_MAX)
    1957                 :          0 :                         return -ENOBUFS;
    1958                 :            : 
    1959         [ -  + ]:        188 :                 if (!GREEDY_REALLOC(bus->wqueue, bus->wqueue_allocated, bus->wqueue_size + 1))
    1960                 :          0 :                         return -ENOMEM;
    1961                 :            : 
    1962                 :        188 :                 bus->wqueue[bus->wqueue_size++] = bus_message_ref_queued(m, bus);
    1963                 :            :         }
    1964                 :            : 
    1965                 :        556 : finish:
    1966         [ +  + ]:        556 :         if (cookie)
    1967                 :        348 :                 *cookie = BUS_MESSAGE_COOKIE(m);
    1968                 :            : 
    1969                 :        556 :         return 1;
    1970                 :            : }
    1971                 :            : 
    1972                 :          0 : _public_ int sd_bus_send_to(sd_bus *bus, sd_bus_message *m, const char *destination, uint64_t *cookie) {
    1973                 :            :         int r;
    1974                 :            : 
    1975   [ #  #  #  # ]:          0 :         assert_return(m, -EINVAL);
    1976                 :            : 
    1977         [ #  # ]:          0 :         if (!bus)
    1978                 :          0 :                 bus = m->bus;
    1979                 :            : 
    1980   [ #  #  #  # ]:          0 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    1981                 :            : 
    1982         [ #  # ]:          0 :         if (!BUS_IS_OPEN(bus->state))
    1983                 :          0 :                 return -ENOTCONN;
    1984                 :            : 
    1985         [ #  # ]:          0 :         if (!streq_ptr(m->destination, destination)) {
    1986                 :            : 
    1987         [ #  # ]:          0 :                 if (!destination)
    1988                 :          0 :                         return -EEXIST;
    1989                 :            : 
    1990                 :          0 :                 r = sd_bus_message_set_destination(m, destination);
    1991         [ #  # ]:          0 :                 if (r < 0)
    1992                 :          0 :                         return r;
    1993                 :            :         }
    1994                 :            : 
    1995                 :          0 :         return sd_bus_send(bus, m, cookie);
    1996                 :            : }
    1997                 :            : 
    1998                 :        348 : static usec_t calc_elapse(sd_bus *bus, uint64_t usec) {
    1999         [ -  + ]:        348 :         assert(bus);
    2000                 :            : 
    2001         [ -  + ]:        348 :         if (usec == (uint64_t) -1)
    2002                 :          0 :                 return 0;
    2003                 :            : 
    2004                 :            :         /* We start all timeouts the instant we enter BUS_HELLO/BUS_RUNNING state, so that the don't run in parallel
    2005                 :            :          * with any connection setup states. Hence, if a method callback is started earlier than that we just store the
    2006                 :            :          * relative timestamp, and afterwards the absolute one. */
    2007                 :            : 
    2008   [ +  +  +  + ]:        348 :         if (IN_SET(bus->state, BUS_WATCH_BIND, BUS_OPENING, BUS_AUTHENTICATING))
    2009                 :        172 :                 return usec;
    2010                 :            :         else
    2011                 :        176 :                 return now(CLOCK_MONOTONIC) + usec;
    2012                 :            : }
    2013                 :            : 
    2014                 :         64 : static int timeout_compare(const void *a, const void *b) {
    2015                 :         64 :         const struct reply_callback *x = a, *y = b;
    2016                 :            : 
    2017   [ +  -  -  + ]:         64 :         if (x->timeout_usec != 0 && y->timeout_usec == 0)
    2018                 :          0 :                 return -1;
    2019                 :            : 
    2020   [ -  +  #  # ]:         64 :         if (x->timeout_usec == 0 && y->timeout_usec != 0)
    2021                 :          0 :                 return 1;
    2022                 :            : 
    2023         [ +  + ]:         64 :         return CMP(x->timeout_usec, y->timeout_usec);
    2024                 :            : }
    2025                 :            : 
    2026                 :        184 : _public_ int sd_bus_call_async(
    2027                 :            :                 sd_bus *bus,
    2028                 :            :                 sd_bus_slot **slot,
    2029                 :            :                 sd_bus_message *_m,
    2030                 :            :                 sd_bus_message_handler_t callback,
    2031                 :            :                 void *userdata,
    2032                 :            :                 uint64_t usec) {
    2033                 :            : 
    2034                 :        368 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = sd_bus_message_ref(_m);
    2035                 :        184 :         _cleanup_(sd_bus_slot_unrefp) sd_bus_slot *s = NULL;
    2036                 :            :         int r;
    2037                 :            : 
    2038   [ -  +  -  + ]:        184 :         assert_return(m, -EINVAL);
    2039   [ -  +  -  + ]:        184 :         assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
    2040   [ -  +  #  #  :        184 :         assert_return(!m->sealed || (!!callback == !(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)), -EINVAL);
                   -  + ]
    2041                 :            : 
    2042         [ -  + ]:        184 :         if (!bus)
    2043                 :          0 :                 bus = m->bus;
    2044                 :            : 
    2045   [ -  +  -  + ]:        184 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    2046                 :            : 
    2047         [ -  + ]:        184 :         if (!BUS_IS_OPEN(bus->state))
    2048                 :          0 :                 return -ENOTCONN;
    2049                 :            : 
    2050                 :            :         /* If no callback is specified and there's no interest in a slot, then there's no reason to ask for a reply */
    2051   [ +  +  +  -  :        184 :         if (!callback && !slot && !m->sealed)
                   +  - ]
    2052                 :          4 :                 m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
    2053                 :            : 
    2054                 :        184 :         r = ordered_hashmap_ensure_allocated(&bus->reply_callbacks, &uint64_hash_ops);
    2055         [ -  + ]:        184 :         if (r < 0)
    2056                 :          0 :                 return r;
    2057                 :            : 
    2058                 :        184 :         r = prioq_ensure_allocated(&bus->reply_callbacks_prioq, timeout_compare);
    2059         [ -  + ]:        184 :         if (r < 0)
    2060                 :          0 :                 return r;
    2061                 :            : 
    2062                 :        184 :         r = bus_seal_message(bus, m, usec);
    2063         [ -  + ]:        184 :         if (r < 0)
    2064                 :          0 :                 return r;
    2065                 :            : 
    2066                 :        184 :         r = bus_remarshal_message(bus, &m);
    2067         [ -  + ]:        184 :         if (r < 0)
    2068                 :          0 :                 return r;
    2069                 :            : 
    2070   [ +  +  +  + ]:        184 :         if (slot || callback) {
    2071                 :        180 :                 s = bus_slot_allocate(bus, !slot, BUS_REPLY_CALLBACK, sizeof(struct reply_callback), userdata);
    2072         [ -  + ]:        180 :                 if (!s)
    2073                 :          0 :                         return -ENOMEM;
    2074                 :            : 
    2075                 :        180 :                 s->reply_callback.callback = callback;
    2076                 :            : 
    2077                 :        180 :                 s->reply_callback.cookie = BUS_MESSAGE_COOKIE(m);
    2078                 :        180 :                 r = ordered_hashmap_put(bus->reply_callbacks, &s->reply_callback.cookie, &s->reply_callback);
    2079         [ -  + ]:        180 :                 if (r < 0) {
    2080                 :          0 :                         s->reply_callback.cookie = 0;
    2081                 :          0 :                         return r;
    2082                 :            :                 }
    2083                 :            : 
    2084                 :        180 :                 s->reply_callback.timeout_usec = calc_elapse(bus, m->timeout);
    2085         [ +  - ]:        180 :                 if (s->reply_callback.timeout_usec != 0) {
    2086                 :        180 :                         r = prioq_put(bus->reply_callbacks_prioq, &s->reply_callback, &s->reply_callback.prioq_idx);
    2087         [ -  + ]:        180 :                         if (r < 0) {
    2088                 :          0 :                                 s->reply_callback.timeout_usec = 0;
    2089                 :          0 :                                 return r;
    2090                 :            :                         }
    2091                 :            :                 }
    2092                 :            :         }
    2093                 :            : 
    2094         [ +  + ]:        184 :         r = sd_bus_send(bus, m, s ? &s->reply_callback.cookie : NULL);
    2095         [ -  + ]:        184 :         if (r < 0)
    2096                 :          0 :                 return r;
    2097                 :            : 
    2098         [ +  + ]:        184 :         if (slot)
    2099                 :         64 :                 *slot = s;
    2100                 :        184 :         s = NULL;
    2101                 :            : 
    2102                 :        184 :         return r;
    2103                 :            : }
    2104                 :            : 
    2105                 :        356 : int bus_ensure_running(sd_bus *bus) {
    2106                 :            :         int r;
    2107                 :            : 
    2108         [ -  + ]:        356 :         assert(bus);
    2109                 :            : 
    2110   [ -  +  -  + ]:        356 :         if (IN_SET(bus->state, BUS_UNSET, BUS_CLOSED, BUS_CLOSING))
    2111                 :          0 :                 return -ENOTCONN;
    2112         [ +  + ]:        356 :         if (bus->state == BUS_RUNNING)
    2113                 :        231 :                 return 1;
    2114                 :            : 
    2115                 :            :         for (;;) {
    2116                 :        437 :                 r = sd_bus_process(bus, NULL);
    2117         [ +  + ]:        437 :                 if (r < 0)
    2118                 :          4 :                         return r;
    2119         [ +  + ]:        433 :                 if (bus->state == BUS_RUNNING)
    2120                 :        121 :                         return 1;
    2121         [ +  + ]:        312 :                 if (r > 0)
    2122                 :        172 :                         continue;
    2123                 :            : 
    2124                 :        140 :                 r = sd_bus_wait(bus, (uint64_t) -1);
    2125         [ -  + ]:        140 :                 if (r < 0)
    2126                 :          0 :                         return r;
    2127                 :            :         }
    2128                 :            : }
    2129                 :            : 
    2130                 :        172 : _public_ int sd_bus_call(
    2131                 :            :                 sd_bus *bus,
    2132                 :            :                 sd_bus_message *_m,
    2133                 :            :                 uint64_t usec,
    2134                 :            :                 sd_bus_error *error,
    2135                 :            :                 sd_bus_message **reply) {
    2136                 :            : 
    2137                 :        344 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = sd_bus_message_ref(_m);
    2138                 :            :         usec_t timeout;
    2139                 :            :         uint64_t cookie;
    2140                 :            :         size_t i;
    2141                 :            :         int r;
    2142                 :            : 
    2143   [ -  +  -  + ]:        172 :         bus_assert_return(m, -EINVAL, error);
    2144   [ -  +  -  + ]:        172 :         bus_assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL, error);
    2145   [ -  +  -  + ]:        172 :         bus_assert_return(!(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED), -EINVAL, error);
    2146   [ -  +  -  + ]:        172 :         bus_assert_return(!bus_error_is_dirty(error), -EINVAL, error);
    2147                 :            : 
    2148         [ -  + ]:        172 :         if (!bus)
    2149                 :          0 :                 bus = m->bus;
    2150                 :            : 
    2151   [ -  +  -  + ]:        172 :         bus_assert_return(!bus_pid_changed(bus), -ECHILD, error);
    2152                 :            : 
    2153         [ -  + ]:        172 :         if (!BUS_IS_OPEN(bus->state)) {
    2154                 :          0 :                 r = -ENOTCONN;
    2155                 :          0 :                 goto fail;
    2156                 :            :         }
    2157                 :            : 
    2158                 :        172 :         r = bus_ensure_running(bus);
    2159         [ +  + ]:        172 :         if (r < 0)
    2160                 :          4 :                 goto fail;
    2161                 :            : 
    2162                 :        168 :         i = bus->rqueue_size;
    2163                 :            : 
    2164                 :        168 :         r = bus_seal_message(bus, m, usec);
    2165         [ -  + ]:        168 :         if (r < 0)
    2166                 :          0 :                 goto fail;
    2167                 :            : 
    2168                 :        168 :         r = bus_remarshal_message(bus, &m);
    2169         [ -  + ]:        168 :         if (r < 0)
    2170                 :          0 :                 goto fail;
    2171                 :            : 
    2172                 :        168 :         r = sd_bus_send(bus, m, &cookie);
    2173         [ -  + ]:        168 :         if (r < 0)
    2174                 :          0 :                 goto fail;
    2175                 :            : 
    2176                 :        168 :         timeout = calc_elapse(bus, m->timeout);
    2177                 :            : 
    2178                 :        516 :         for (;;) {
    2179                 :            :                 usec_t left;
    2180                 :            : 
    2181         [ +  + ]:        736 :                 while (i < bus->rqueue_size) {
    2182      [ +  +  - ]:        216 :                         _cleanup_(sd_bus_message_unrefp) sd_bus_message *incoming = NULL;
    2183                 :            : 
    2184                 :        216 :                         incoming = sd_bus_message_ref(bus->rqueue[i]);
    2185                 :            : 
    2186         [ +  + ]:        216 :                         if (incoming->reply_cookie == cookie) {
    2187                 :            :                                 /* Found a match! */
    2188                 :            : 
    2189                 :        164 :                                 rqueue_drop_one(bus, i);
    2190         [ +  + ]:        164 :                                 log_debug_bus_message(incoming);
    2191                 :            : 
    2192         [ +  + ]:        164 :                                 if (incoming->header->type == SD_BUS_MESSAGE_METHOD_RETURN) {
    2193                 :            : 
    2194   [ -  +  #  # ]:        148 :                                         if (incoming->n_fds <= 0 || bus->accept_fd) {
    2195         [ +  + ]:        148 :                                                 if (reply)
    2196                 :         92 :                                                         *reply = TAKE_PTR(incoming);
    2197                 :            : 
    2198                 :        148 :                                                 return 1;
    2199                 :            :                                         }
    2200                 :            : 
    2201                 :          0 :                                         return sd_bus_error_setf(error, SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Reply message contained file descriptors which I couldn't accept. Sorry.");
    2202                 :            : 
    2203         [ +  - ]:         16 :                                 } else if (incoming->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
    2204                 :         16 :                                         return sd_bus_error_copy(error, &incoming->error);
    2205                 :            :                                 else {
    2206                 :          0 :                                         r = -EIO;
    2207                 :          0 :                                         goto fail;
    2208                 :            :                                 }
    2209                 :            : 
    2210         [ +  + ]:         52 :                         } else if (BUS_MESSAGE_COOKIE(incoming) == cookie &&
    2211         [ +  - ]:         16 :                                    bus->unique_name &&
    2212         [ +  - ]:         16 :                                    incoming->sender &&
    2213         [ -  + ]:         16 :                                    streq(bus->unique_name, incoming->sender)) {
    2214                 :            : 
    2215                 :          0 :                                 rqueue_drop_one(bus, i);
    2216                 :            : 
    2217                 :            :                                 /* Our own message? Somebody is trying to send its own client a message,
    2218                 :            :                                  * let's not dead-lock, let's fail immediately. */
    2219                 :            : 
    2220                 :          0 :                                 r = -ELOOP;
    2221                 :          0 :                                 goto fail;
    2222                 :            :                         }
    2223                 :            : 
    2224                 :            :                         /* Try to read more, right-away */
    2225                 :         52 :                         i++;
    2226                 :            :                 }
    2227                 :            : 
    2228                 :        520 :                 r = bus_read_message(bus, false, 0);
    2229         [ -  + ]:        520 :                 if (r < 0) {
    2230         [ #  # ]:          0 :                         if (ERRNO_IS_DISCONNECT(r)) {
    2231                 :          0 :                                 bus_enter_closing(bus);
    2232                 :          0 :                                 r = -ECONNRESET;
    2233                 :            :                         }
    2234                 :            : 
    2235                 :          0 :                         goto fail;
    2236                 :            :                 }
    2237         [ +  + ]:        520 :                 if (r > 0)
    2238                 :        356 :                         continue;
    2239                 :            : 
    2240         [ +  - ]:        164 :                 if (timeout > 0) {
    2241                 :            :                         usec_t n;
    2242                 :            : 
    2243                 :        164 :                         n = now(CLOCK_MONOTONIC);
    2244         [ -  + ]:        164 :                         if (n >= timeout) {
    2245                 :          0 :                                 r = -ETIMEDOUT;
    2246                 :          0 :                                 goto fail;
    2247                 :            :                         }
    2248                 :            : 
    2249                 :        164 :                         left = timeout - n;
    2250                 :            :                 } else
    2251                 :          0 :                         left = (uint64_t) -1;
    2252                 :            : 
    2253                 :        164 :                 r = bus_poll(bus, true, left);
    2254         [ -  + ]:        164 :                 if (r < 0)
    2255                 :          0 :                         goto fail;
    2256         [ +  + ]:        164 :                 if (r == 0) {
    2257                 :          4 :                         r = -ETIMEDOUT;
    2258                 :          4 :                         goto fail;
    2259                 :            :                 }
    2260                 :            : 
    2261                 :        160 :                 r = dispatch_wqueue(bus);
    2262         [ -  + ]:        160 :                 if (r < 0) {
    2263         [ #  # ]:          0 :                         if (ERRNO_IS_DISCONNECT(r)) {
    2264                 :          0 :                                 bus_enter_closing(bus);
    2265                 :          0 :                                 r = -ECONNRESET;
    2266                 :            :                         }
    2267                 :            : 
    2268                 :          0 :                         goto fail;
    2269                 :            :                 }
    2270                 :            :         }
    2271                 :            : 
    2272                 :          8 : fail:
    2273                 :          8 :         return sd_bus_error_set_errno(error, r);
    2274                 :            : }
    2275                 :            : 
    2276                 :          4 : _public_ int sd_bus_get_fd(sd_bus *bus) {
    2277                 :            : 
    2278   [ -  +  -  + ]:          4 :         assert_return(bus, -EINVAL);
    2279   [ -  +  -  + ]:          4 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    2280   [ -  +  -  + ]:          4 :         assert_return(bus->input_fd == bus->output_fd, -EPERM);
    2281   [ -  +  -  + ]:          4 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    2282                 :            : 
    2283         [ -  + ]:          4 :         if (bus->state == BUS_CLOSED)
    2284                 :          0 :                 return -ENOTCONN;
    2285                 :            : 
    2286         [ -  + ]:          4 :         if (bus->inotify_fd >= 0)
    2287                 :          0 :                 return bus->inotify_fd;
    2288                 :            : 
    2289         [ +  - ]:          4 :         if (bus->input_fd >= 0)
    2290                 :          4 :                 return bus->input_fd;
    2291                 :            : 
    2292                 :          0 :         return -ENOTCONN;
    2293                 :            : }
    2294                 :            : 
    2295                 :        666 : _public_ int sd_bus_get_events(sd_bus *bus) {
    2296                 :        666 :         int flags = 0;
    2297                 :            : 
    2298   [ -  +  -  + ]:        666 :         assert_return(bus, -EINVAL);
    2299   [ -  +  -  + ]:        666 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    2300   [ -  +  -  + ]:        666 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    2301                 :            : 
    2302   [ -  -  -  +  :        666 :         switch (bus->state) {
                +  +  - ]
    2303                 :            : 
    2304                 :          0 :         case BUS_UNSET:
    2305                 :            :         case BUS_CLOSED:
    2306                 :          0 :                 return -ENOTCONN;
    2307                 :            : 
    2308                 :          0 :         case BUS_WATCH_BIND:
    2309                 :          0 :                 flags |= POLLIN;
    2310                 :          0 :                 break;
    2311                 :            : 
    2312                 :          0 :         case BUS_OPENING:
    2313                 :          0 :                 flags |= POLLOUT;
    2314                 :          0 :                 break;
    2315                 :            : 
    2316                 :        157 :         case BUS_AUTHENTICATING:
    2317         [ +  + ]:        157 :                 if (bus_socket_auth_needs_write(bus))
    2318                 :         12 :                         flags |= POLLOUT;
    2319                 :            : 
    2320                 :        157 :                 flags |= POLLIN;
    2321                 :        157 :                 break;
    2322                 :            : 
    2323                 :        505 :         case BUS_RUNNING:
    2324                 :            :         case BUS_HELLO:
    2325         [ +  + ]:        505 :                 if (bus->rqueue_size <= 0)
    2326                 :        459 :                         flags |= POLLIN;
    2327         [ +  + ]:        505 :                 if (bus->wqueue_size > 0)
    2328                 :         31 :                         flags |= POLLOUT;
    2329                 :        505 :                 break;
    2330                 :            : 
    2331                 :          4 :         case BUS_CLOSING:
    2332                 :          4 :                 break;
    2333                 :            : 
    2334                 :          0 :         default:
    2335                 :          0 :                 assert_not_reached("Unknown state");
    2336                 :            :         }
    2337                 :            : 
    2338                 :        666 :         return flags;
    2339                 :            : }
    2340                 :            : 
    2341                 :        502 : _public_ int sd_bus_get_timeout(sd_bus *bus, uint64_t *timeout_usec) {
    2342                 :            :         struct reply_callback *c;
    2343                 :            : 
    2344   [ -  +  -  + ]:        502 :         assert_return(bus, -EINVAL);
    2345   [ -  +  -  + ]:        502 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    2346   [ -  +  -  + ]:        502 :         assert_return(timeout_usec, -EINVAL);
    2347   [ -  +  -  + ]:        502 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    2348                 :            : 
    2349   [ +  +  -  + ]:        502 :         if (!BUS_IS_OPEN(bus->state) && bus->state != BUS_CLOSING)
    2350                 :          0 :                 return -ENOTCONN;
    2351                 :            : 
    2352         [ +  + ]:        502 :         if (bus->track_queue) {
    2353                 :          4 :                 *timeout_usec = 0;
    2354                 :          4 :                 return 1;
    2355                 :            :         }
    2356                 :            : 
    2357   [ +  +  +  -  :        498 :         switch (bus->state) {
                      - ]
    2358                 :            : 
    2359                 :        157 :         case BUS_AUTHENTICATING:
    2360                 :        157 :                 *timeout_usec = bus->auth_timeout;
    2361                 :        157 :                 return 1;
    2362                 :            : 
    2363                 :        337 :         case BUS_RUNNING:
    2364                 :            :         case BUS_HELLO:
    2365         [ +  + ]:        337 :                 if (bus->rqueue_size > 0) {
    2366                 :         12 :                         *timeout_usec = 0;
    2367                 :         12 :                         return 1;
    2368                 :            :                 }
    2369                 :            : 
    2370                 :        325 :                 c = prioq_peek(bus->reply_callbacks_prioq);
    2371         [ +  + ]:        325 :                 if (!c) {
    2372                 :        184 :                         *timeout_usec = (uint64_t) -1;
    2373                 :        184 :                         return 0;
    2374                 :            :                 }
    2375                 :            : 
    2376         [ -  + ]:        141 :                 if (c->timeout_usec == 0) {
    2377                 :          0 :                         *timeout_usec = (uint64_t) -1;
    2378                 :          0 :                         return 0;
    2379                 :            :                 }
    2380                 :            : 
    2381                 :        141 :                 *timeout_usec = c->timeout_usec;
    2382                 :        141 :                 return 1;
    2383                 :            : 
    2384                 :          4 :         case BUS_CLOSING:
    2385                 :          4 :                 *timeout_usec = 0;
    2386                 :          4 :                 return 1;
    2387                 :            : 
    2388                 :          0 :         case BUS_WATCH_BIND:
    2389                 :            :         case BUS_OPENING:
    2390                 :          0 :                 *timeout_usec = (uint64_t) -1;
    2391                 :          0 :                 return 0;
    2392                 :            : 
    2393                 :          0 :         default:
    2394                 :          0 :                 assert_not_reached("Unknown or unexpected stat");
    2395                 :            :         }
    2396                 :            : }
    2397                 :            : 
    2398                 :        671 : static int process_timeout(sd_bus *bus) {
    2399                 :        671 :         _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
    2400                 :        671 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message* m = NULL;
    2401                 :            :         struct reply_callback *c;
    2402                 :            :         sd_bus_slot *slot;
    2403                 :            :         bool is_hello;
    2404                 :            :         usec_t n;
    2405                 :            :         int r;
    2406                 :            : 
    2407         [ -  + ]:        671 :         assert(bus);
    2408   [ +  -  -  + ]:        671 :         assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO));
    2409                 :            : 
    2410                 :        671 :         c = prioq_peek(bus->reply_callbacks_prioq);
    2411         [ +  + ]:        671 :         if (!c)
    2412                 :        371 :                 return 0;
    2413                 :            : 
    2414                 :        300 :         n = now(CLOCK_MONOTONIC);
    2415         [ +  + ]:        300 :         if (c->timeout_usec > n)
    2416                 :        296 :                 return 0;
    2417                 :            : 
    2418                 :          4 :         r = bus_message_new_synthetic_error(
    2419                 :            :                         bus,
    2420                 :            :                         c->cookie,
    2421                 :          4 :                         &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Method call timed out"),
    2422                 :            :                         &m);
    2423         [ -  + ]:          4 :         if (r < 0)
    2424                 :          0 :                 return r;
    2425                 :            : 
    2426                 :          4 :         m->read_counter = ++bus->read_counter;
    2427                 :            : 
    2428                 :          4 :         r = bus_seal_synthetic_message(bus, m);
    2429         [ -  + ]:          4 :         if (r < 0)
    2430                 :          0 :                 return r;
    2431                 :            : 
    2432         [ -  + ]:          4 :         assert_se(prioq_pop(bus->reply_callbacks_prioq) == c);
    2433                 :          4 :         c->timeout_usec = 0;
    2434                 :            : 
    2435                 :          4 :         ordered_hashmap_remove(bus->reply_callbacks, &c->cookie);
    2436                 :          4 :         c->cookie = 0;
    2437                 :            : 
    2438                 :          4 :         slot = container_of(c, sd_bus_slot, reply_callback);
    2439                 :            : 
    2440                 :          4 :         bus->iteration_counter++;
    2441                 :            : 
    2442   [ -  +  #  # ]:          4 :         is_hello = bus->state == BUS_HELLO && c->callback == hello_callback;
    2443                 :            : 
    2444                 :          4 :         bus->current_message = m;
    2445                 :          4 :         bus->current_slot = sd_bus_slot_ref(slot);
    2446                 :          4 :         bus->current_handler = c->callback;
    2447                 :          4 :         bus->current_userdata = slot->userdata;
    2448                 :          4 :         r = c->callback(m, slot->userdata, &error_buffer);
    2449                 :          4 :         bus->current_userdata = NULL;
    2450                 :          4 :         bus->current_handler = NULL;
    2451                 :          4 :         bus->current_slot = NULL;
    2452                 :          4 :         bus->current_message = NULL;
    2453                 :            : 
    2454         [ +  - ]:          4 :         if (slot->floating)
    2455                 :          4 :                 bus_slot_disconnect(slot, true);
    2456                 :            : 
    2457                 :          4 :         sd_bus_slot_unref(slot);
    2458                 :            : 
    2459                 :            :         /* When this is the hello message and it timed out, then make sure to propagate the error up, don't just log
    2460                 :            :          * and ignore the callback handler's return value. */
    2461         [ -  + ]:          4 :         if (is_hello)
    2462                 :          0 :                 return r;
    2463                 :            : 
    2464                 :          4 :         return bus_maybe_reply_error(m, r, &error_buffer);
    2465                 :            : }
    2466                 :            : 
    2467                 :        358 : static int process_hello(sd_bus *bus, sd_bus_message *m) {
    2468         [ -  + ]:        358 :         assert(bus);
    2469         [ -  + ]:        358 :         assert(m);
    2470                 :            : 
    2471         [ +  + ]:        358 :         if (bus->state != BUS_HELLO)
    2472                 :        262 :                 return 0;
    2473                 :            : 
    2474                 :            :         /* Let's make sure the first message on the bus is the HELLO
    2475                 :            :          * reply. But note that we don't actually parse the message
    2476                 :            :          * here (we leave that to the usual handling), we just verify
    2477                 :            :          * we don't let any earlier msg through. */
    2478                 :            : 
    2479   [ +  -  -  + ]:         96 :         if (!IN_SET(m->header->type, SD_BUS_MESSAGE_METHOD_RETURN, SD_BUS_MESSAGE_METHOD_ERROR))
    2480                 :          0 :                 return -EIO;
    2481                 :            : 
    2482         [ -  + ]:         96 :         if (m->reply_cookie != 1)
    2483                 :          0 :                 return -EIO;
    2484                 :            : 
    2485                 :         96 :         return 0;
    2486                 :            : }
    2487                 :            : 
    2488                 :        358 : static int process_reply(sd_bus *bus, sd_bus_message *m) {
    2489                 :        358 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *synthetic_reply = NULL;
    2490                 :        358 :         _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
    2491                 :            :         struct reply_callback *c;
    2492                 :            :         sd_bus_slot *slot;
    2493                 :            :         bool is_hello;
    2494                 :            :         int r;
    2495                 :            : 
    2496         [ -  + ]:        358 :         assert(bus);
    2497         [ -  + ]:        358 :         assert(m);
    2498                 :            : 
    2499   [ +  +  +  + ]:        358 :         if (!IN_SET(m->header->type, SD_BUS_MESSAGE_METHOD_RETURN, SD_BUS_MESSAGE_METHOD_ERROR))
    2500                 :        239 :                 return 0;
    2501                 :            : 
    2502   [ +  +  +  +  :        119 :         if (m->destination && bus->unique_name && !streq_ptr(m->destination, bus->unique_name))
                   -  + ]
    2503                 :          0 :                 return 0;
    2504                 :            : 
    2505                 :        119 :         c = ordered_hashmap_remove(bus->reply_callbacks, &m->reply_cookie);
    2506         [ -  + ]:        119 :         if (!c)
    2507                 :          0 :                 return 0;
    2508                 :            : 
    2509                 :        119 :         c->cookie = 0;
    2510                 :            : 
    2511                 :        119 :         slot = container_of(c, sd_bus_slot, reply_callback);
    2512                 :            : 
    2513   [ -  +  #  # ]:        119 :         if (m->n_fds > 0 && !bus->accept_fd) {
    2514                 :            : 
    2515                 :            :                 /* If the reply contained a file descriptor which we
    2516                 :            :                  * didn't want we pass an error instead. */
    2517                 :            : 
    2518                 :          0 :                 r = bus_message_new_synthetic_error(
    2519                 :            :                                 bus,
    2520                 :            :                                 m->reply_cookie,
    2521                 :          0 :                                 &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Reply message contained file descriptor"),
    2522                 :            :                                 &synthetic_reply);
    2523         [ #  # ]:          0 :                 if (r < 0)
    2524                 :          0 :                         return r;
    2525                 :            : 
    2526                 :            :                 /* Copy over original timestamp */
    2527                 :          0 :                 synthetic_reply->realtime = m->realtime;
    2528                 :          0 :                 synthetic_reply->monotonic = m->monotonic;
    2529                 :          0 :                 synthetic_reply->seqnum = m->seqnum;
    2530                 :          0 :                 synthetic_reply->read_counter = m->read_counter;
    2531                 :            : 
    2532                 :          0 :                 r = bus_seal_synthetic_message(bus, synthetic_reply);
    2533         [ #  # ]:          0 :                 if (r < 0)
    2534                 :          0 :                         return r;
    2535                 :            : 
    2536                 :          0 :                 m = synthetic_reply;
    2537                 :            :         } else {
    2538                 :        119 :                 r = sd_bus_message_rewind(m, true);
    2539         [ -  + ]:        119 :                 if (r < 0)
    2540                 :          0 :                         return r;
    2541                 :            :         }
    2542                 :            : 
    2543         [ +  - ]:        119 :         if (c->timeout_usec != 0) {
    2544                 :        119 :                 prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
    2545                 :        119 :                 c->timeout_usec = 0;
    2546                 :            :         }
    2547                 :            : 
    2548   [ +  +  +  - ]:        119 :         is_hello = bus->state == BUS_HELLO && c->callback == hello_callback;
    2549                 :            : 
    2550                 :        119 :         bus->current_slot = sd_bus_slot_ref(slot);
    2551                 :        119 :         bus->current_handler = c->callback;
    2552                 :        119 :         bus->current_userdata = slot->userdata;
    2553                 :        119 :         r = c->callback(m, slot->userdata, &error_buffer);
    2554                 :        119 :         bus->current_userdata = NULL;
    2555                 :        119 :         bus->current_handler = NULL;
    2556                 :        119 :         bus->current_slot = NULL;
    2557                 :            : 
    2558         [ +  - ]:        119 :         if (slot->floating)
    2559                 :        119 :                 bus_slot_disconnect(slot, true);
    2560                 :            : 
    2561                 :        119 :         sd_bus_slot_unref(slot);
    2562                 :            : 
    2563                 :            :         /* When this is the hello message and it failed, then make sure to propagate the error up, don't just log and
    2564                 :            :          * ignore the callback handler's return value. */
    2565         [ +  + ]:        119 :         if (is_hello)
    2566                 :         96 :                 return r;
    2567                 :            : 
    2568                 :         23 :         return bus_maybe_reply_error(m, r, &error_buffer);
    2569                 :            : }
    2570                 :            : 
    2571                 :        247 : static int process_filter(sd_bus *bus, sd_bus_message *m) {
    2572                 :        247 :         _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
    2573                 :            :         struct filter_callback *l;
    2574                 :            :         int r;
    2575                 :            : 
    2576         [ -  + ]:        247 :         assert(bus);
    2577         [ -  + ]:        247 :         assert(m);
    2578                 :            : 
    2579                 :            :         do {
    2580                 :        247 :                 bus->filter_callbacks_modified = false;
    2581                 :            : 
    2582         [ -  + ]:        247 :                 LIST_FOREACH(callbacks, l, bus->filter_callbacks) {
    2583                 :            :                         sd_bus_slot *slot;
    2584                 :            : 
    2585         [ #  # ]:          0 :                         if (bus->filter_callbacks_modified)
    2586                 :          0 :                                 break;
    2587                 :            : 
    2588                 :            :                         /* Don't run this more than once per iteration */
    2589         [ #  # ]:          0 :                         if (l->last_iteration == bus->iteration_counter)
    2590                 :          0 :                                 continue;
    2591                 :            : 
    2592                 :          0 :                         l->last_iteration = bus->iteration_counter;
    2593                 :            : 
    2594                 :          0 :                         r = sd_bus_message_rewind(m, true);
    2595         [ #  # ]:          0 :                         if (r < 0)
    2596                 :          0 :                                 return r;
    2597                 :            : 
    2598                 :          0 :                         slot = container_of(l, sd_bus_slot, filter_callback);
    2599                 :            : 
    2600                 :          0 :                         bus->current_slot = sd_bus_slot_ref(slot);
    2601                 :          0 :                         bus->current_handler = l->callback;
    2602                 :          0 :                         bus->current_userdata = slot->userdata;
    2603                 :          0 :                         r = l->callback(m, slot->userdata, &error_buffer);
    2604                 :          0 :                         bus->current_userdata = NULL;
    2605                 :          0 :                         bus->current_handler = NULL;
    2606                 :          0 :                         bus->current_slot = sd_bus_slot_unref(slot);
    2607                 :            : 
    2608                 :          0 :                         r = bus_maybe_reply_error(m, r, &error_buffer);
    2609         [ #  # ]:          0 :                         if (r != 0)
    2610                 :          0 :                                 return r;
    2611                 :            : 
    2612                 :            :                 }
    2613                 :            : 
    2614         [ -  + ]:        247 :         } while (bus->filter_callbacks_modified);
    2615                 :            : 
    2616                 :        247 :         return 0;
    2617                 :            : }
    2618                 :            : 
    2619                 :        247 : static int process_match(sd_bus *bus, sd_bus_message *m) {
    2620                 :            :         int r;
    2621                 :            : 
    2622         [ -  + ]:        247 :         assert(bus);
    2623         [ -  + ]:        247 :         assert(m);
    2624                 :            : 
    2625                 :            :         do {
    2626                 :        251 :                 bus->match_callbacks_modified = false;
    2627                 :            : 
    2628                 :        251 :                 r = bus_match_run(bus, &bus->match_callbacks, m);
    2629         [ -  + ]:        251 :                 if (r != 0)
    2630                 :          0 :                         return r;
    2631                 :            : 
    2632         [ +  + ]:        251 :         } while (bus->match_callbacks_modified);
    2633                 :            : 
    2634                 :        247 :         return 0;
    2635                 :            : }
    2636                 :            : 
    2637                 :        243 : static int process_builtin(sd_bus *bus, sd_bus_message *m) {
    2638                 :        243 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
    2639                 :            :         int r;
    2640                 :            : 
    2641         [ -  + ]:        243 :         assert(bus);
    2642         [ -  + ]:        243 :         assert(m);
    2643                 :            : 
    2644         [ -  + ]:        243 :         if (bus->is_monitor)
    2645                 :          0 :                 return 0;
    2646                 :            : 
    2647         [ -  + ]:        243 :         if (bus->manual_peer_interface)
    2648                 :          0 :                 return 0;
    2649                 :            : 
    2650         [ +  + ]:        243 :         if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
    2651                 :         75 :                 return 0;
    2652                 :            : 
    2653         [ +  + ]:        168 :         if (!streq_ptr(m->interface, "org.freedesktop.DBus.Peer"))
    2654                 :        164 :                 return 0;
    2655                 :            : 
    2656         [ -  + ]:          4 :         if (m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)
    2657                 :          0 :                 return 1;
    2658                 :            : 
    2659         [ -  + ]:          4 :         if (streq_ptr(m->member, "Ping"))
    2660                 :          0 :                 r = sd_bus_message_new_method_return(m, &reply);
    2661         [ +  - ]:          4 :         else if (streq_ptr(m->member, "GetMachineId")) {
    2662                 :            :                 sd_id128_t id;
    2663                 :            :                 char sid[33];
    2664                 :            : 
    2665                 :          4 :                 r = sd_id128_get_machine(&id);
    2666         [ -  + ]:          4 :                 if (r < 0)
    2667                 :          0 :                         return r;
    2668                 :            : 
    2669                 :          4 :                 r = sd_bus_message_new_method_return(m, &reply);
    2670         [ -  + ]:          4 :                 if (r < 0)
    2671                 :          0 :                         return r;
    2672                 :            : 
    2673                 :          4 :                 r = sd_bus_message_append(reply, "s", sd_id128_to_string(id, sid));
    2674                 :            :         } else {
    2675                 :          0 :                 r = sd_bus_message_new_method_errorf(
    2676                 :            :                                 m, &reply,
    2677                 :            :                                 SD_BUS_ERROR_UNKNOWN_METHOD,
    2678                 :            :                                  "Unknown method '%s' on interface '%s'.", m->member, m->interface);
    2679                 :            :         }
    2680         [ -  + ]:          4 :         if (r < 0)
    2681                 :          0 :                 return r;
    2682                 :            : 
    2683                 :          4 :         r = sd_bus_send(bus, reply, NULL);
    2684         [ -  + ]:          4 :         if (r < 0)
    2685                 :          0 :                 return r;
    2686                 :            : 
    2687                 :          4 :         return 1;
    2688                 :            : }
    2689                 :            : 
    2690                 :        243 : static int process_fd_check(sd_bus *bus, sd_bus_message *m) {
    2691         [ -  + ]:        243 :         assert(bus);
    2692         [ -  + ]:        243 :         assert(m);
    2693                 :            : 
    2694                 :            :         /* If we got a message with a file descriptor which we didn't
    2695                 :            :          * want to accept, then let's drop it. How can this even
    2696                 :            :          * happen? For example, when the kernel queues a message into
    2697                 :            :          * an activatable names's queue which allows fds, and then is
    2698                 :            :          * delivered to us later even though we ourselves did not
    2699                 :            :          * negotiate it. */
    2700                 :            : 
    2701         [ -  + ]:        243 :         if (bus->is_monitor)
    2702                 :          0 :                 return 0;
    2703                 :            : 
    2704         [ +  + ]:        243 :         if (m->n_fds <= 0)
    2705                 :        239 :                 return 0;
    2706                 :            : 
    2707         [ +  - ]:          4 :         if (bus->accept_fd)
    2708                 :          4 :                 return 0;
    2709                 :            : 
    2710         [ #  # ]:          0 :         if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
    2711                 :          0 :                 return 1; /* just eat it up */
    2712                 :            : 
    2713                 :          0 :         return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_INCONSISTENT_MESSAGE, "Message contains file descriptors, which I cannot accept. Sorry.");
    2714                 :            : }
    2715                 :            : 
    2716                 :        358 : static int process_message(sd_bus *bus, sd_bus_message *m) {
    2717                 :            :         int r;
    2718                 :            : 
    2719         [ -  + ]:        358 :         assert(bus);
    2720         [ -  + ]:        358 :         assert(m);
    2721                 :            : 
    2722                 :        358 :         bus->current_message = m;
    2723                 :        358 :         bus->iteration_counter++;
    2724                 :            : 
    2725         [ +  + ]:        358 :         log_debug_bus_message(m);
    2726                 :            : 
    2727                 :        358 :         r = process_hello(bus, m);
    2728         [ -  + ]:        358 :         if (r != 0)
    2729                 :          0 :                 goto finish;
    2730                 :            : 
    2731                 :        358 :         r = process_reply(bus, m);
    2732         [ +  + ]:        358 :         if (r != 0)
    2733                 :        115 :                 goto finish;
    2734                 :            : 
    2735                 :        243 :         r = process_fd_check(bus, m);
    2736         [ -  + ]:        243 :         if (r != 0)
    2737                 :          0 :                 goto finish;
    2738                 :            : 
    2739                 :        243 :         r = process_filter(bus, m);
    2740         [ -  + ]:        243 :         if (r != 0)
    2741                 :          0 :                 goto finish;
    2742                 :            : 
    2743                 :        243 :         r = process_match(bus, m);
    2744         [ -  + ]:        243 :         if (r != 0)
    2745                 :          0 :                 goto finish;
    2746                 :            : 
    2747                 :        243 :         r = process_builtin(bus, m);
    2748         [ +  + ]:        243 :         if (r != 0)
    2749                 :          4 :                 goto finish;
    2750                 :            : 
    2751                 :        239 :         r = bus_process_object(bus, m);
    2752                 :            : 
    2753                 :        358 : finish:
    2754                 :        358 :         bus->current_message = NULL;
    2755                 :        358 :         return r;
    2756                 :            : }
    2757                 :            : 
    2758                 :        567 : static int dispatch_track(sd_bus *bus) {
    2759         [ -  + ]:        567 :         assert(bus);
    2760                 :            : 
    2761         [ +  + ]:        567 :         if (!bus->track_queue)
    2762                 :        563 :                 return 0;
    2763                 :            : 
    2764                 :          4 :         bus_track_dispatch(bus->track_queue);
    2765                 :          4 :         return 1;
    2766                 :            : }
    2767                 :            : 
    2768                 :        671 : static int process_running(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **ret) {
    2769                 :        671 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
    2770                 :            :         int r;
    2771                 :            : 
    2772         [ -  + ]:        671 :         assert(bus);
    2773   [ +  -  -  + ]:        671 :         assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO));
    2774                 :            : 
    2775                 :        671 :         r = process_timeout(bus);
    2776         [ +  + ]:        671 :         if (r != 0)
    2777                 :          4 :                 goto null_message;
    2778                 :            : 
    2779                 :        667 :         r = dispatch_wqueue(bus);
    2780         [ +  + ]:        667 :         if (r != 0)
    2781                 :        100 :                 goto null_message;
    2782                 :            : 
    2783                 :        567 :         r = dispatch_track(bus);
    2784         [ +  + ]:        567 :         if (r != 0)
    2785                 :          4 :                 goto null_message;
    2786                 :            : 
    2787                 :        563 :         r = dispatch_rqueue(bus, hint_priority, priority, &m);
    2788         [ +  + ]:        563 :         if (r < 0)
    2789                 :          4 :                 return r;
    2790         [ +  + ]:        559 :         if (!m)
    2791                 :        201 :                 goto null_message;
    2792                 :            : 
    2793                 :        358 :         r = process_message(bus, m);
    2794         [ +  + ]:        358 :         if (r != 0)
    2795                 :        235 :                 goto null_message;
    2796                 :            : 
    2797         [ +  + ]:        123 :         if (ret) {
    2798                 :         96 :                 r = sd_bus_message_rewind(m, true);
    2799         [ -  + ]:         96 :                 if (r < 0)
    2800                 :          0 :                         return r;
    2801                 :            : 
    2802                 :         96 :                 *ret = TAKE_PTR(m);
    2803                 :         96 :                 return 1;
    2804                 :            :         }
    2805                 :            : 
    2806         [ -  + ]:         27 :         if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL) {
    2807                 :            : 
    2808         [ #  # ]:          0 :                 log_debug("Unprocessed message call sender=%s object=%s interface=%s member=%s",
    2809                 :            :                           strna(sd_bus_message_get_sender(m)),
    2810                 :            :                           strna(sd_bus_message_get_path(m)),
    2811                 :            :                           strna(sd_bus_message_get_interface(m)),
    2812                 :            :                           strna(sd_bus_message_get_member(m)));
    2813                 :            : 
    2814                 :          0 :                 r = sd_bus_reply_method_errorf(
    2815                 :            :                                 m,
    2816                 :            :                                 SD_BUS_ERROR_UNKNOWN_OBJECT,
    2817                 :          0 :                                 "Unknown object '%s'.", m->path);
    2818         [ #  # ]:          0 :                 if (r < 0)
    2819                 :          0 :                         return r;
    2820                 :            :         }
    2821                 :            : 
    2822                 :         27 :         return 1;
    2823                 :            : 
    2824                 :        544 : null_message:
    2825   [ +  -  +  + ]:        544 :         if (r >= 0 && ret)
    2826                 :         51 :                 *ret = NULL;
    2827                 :            : 
    2828                 :        544 :         return r;
    2829                 :            : }
    2830                 :            : 
    2831                 :          4 : static int bus_exit_now(sd_bus *bus) {
    2832         [ -  + ]:          4 :         assert(bus);
    2833                 :            : 
    2834                 :            :         /* Exit due to close, if this is requested. If this is bus object is attached to an event source, invokes
    2835                 :            :          * sd_event_exit(), otherwise invokes libc exit(). */
    2836                 :            : 
    2837         [ -  + ]:          4 :         if (bus->exited) /* did we already exit? */
    2838                 :          0 :                 return 0;
    2839         [ -  + ]:          4 :         if (!bus->exit_triggered) /* was the exit condition triggered? */
    2840                 :          0 :                 return 0;
    2841         [ +  - ]:          4 :         if (!bus->exit_on_disconnect) /* Shall we actually exit on disconnection? */
    2842                 :          4 :                 return 0;
    2843                 :            : 
    2844                 :          0 :         bus->exited = true; /* never exit more than once */
    2845                 :            : 
    2846         [ #  # ]:          0 :         log_debug("Bus connection disconnected, exiting.");
    2847                 :            : 
    2848         [ #  # ]:          0 :         if (bus->event)
    2849                 :          0 :                 return sd_event_exit(bus->event, EXIT_FAILURE);
    2850                 :            :         else
    2851                 :          0 :                 exit(EXIT_FAILURE);
    2852                 :            : 
    2853                 :            :         assert_not_reached("exit() didn't exit?");
    2854                 :            : }
    2855                 :            : 
    2856                 :          0 : static int process_closing_reply_callback(sd_bus *bus, struct reply_callback *c) {
    2857                 :          0 :         _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
    2858                 :          0 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
    2859                 :            :         sd_bus_slot *slot;
    2860                 :            :         int r;
    2861                 :            : 
    2862         [ #  # ]:          0 :         assert(bus);
    2863         [ #  # ]:          0 :         assert(c);
    2864                 :            : 
    2865                 :          0 :         r = bus_message_new_synthetic_error(
    2866                 :            :                         bus,
    2867                 :            :                         c->cookie,
    2868                 :          0 :                         &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_NO_REPLY, "Connection terminated"),
    2869                 :            :                         &m);
    2870         [ #  # ]:          0 :         if (r < 0)
    2871                 :          0 :                 return r;
    2872                 :            : 
    2873                 :          0 :         m->read_counter = ++bus->read_counter;
    2874                 :            : 
    2875                 :          0 :         r = bus_seal_synthetic_message(bus, m);
    2876         [ #  # ]:          0 :         if (r < 0)
    2877                 :          0 :                 return r;
    2878                 :            : 
    2879         [ #  # ]:          0 :         if (c->timeout_usec != 0) {
    2880                 :          0 :                 prioq_remove(bus->reply_callbacks_prioq, c, &c->prioq_idx);
    2881                 :          0 :                 c->timeout_usec = 0;
    2882                 :            :         }
    2883                 :            : 
    2884                 :          0 :         ordered_hashmap_remove(bus->reply_callbacks, &c->cookie);
    2885                 :          0 :         c->cookie = 0;
    2886                 :            : 
    2887                 :          0 :         slot = container_of(c, sd_bus_slot, reply_callback);
    2888                 :            : 
    2889                 :          0 :         bus->iteration_counter++;
    2890                 :            : 
    2891                 :          0 :         bus->current_message = m;
    2892                 :          0 :         bus->current_slot = sd_bus_slot_ref(slot);
    2893                 :          0 :         bus->current_handler = c->callback;
    2894                 :          0 :         bus->current_userdata = slot->userdata;
    2895                 :          0 :         r = c->callback(m, slot->userdata, &error_buffer);
    2896                 :          0 :         bus->current_userdata = NULL;
    2897                 :          0 :         bus->current_handler = NULL;
    2898                 :          0 :         bus->current_slot = NULL;
    2899                 :          0 :         bus->current_message = NULL;
    2900                 :            : 
    2901         [ #  # ]:          0 :         if (slot->floating)
    2902                 :          0 :                 bus_slot_disconnect(slot, true);
    2903                 :            : 
    2904                 :          0 :         sd_bus_slot_unref(slot);
    2905                 :            : 
    2906                 :          0 :         return bus_maybe_reply_error(m, r, &error_buffer);
    2907                 :            : }
    2908                 :            : 
    2909                 :          8 : static int process_closing(sd_bus *bus, sd_bus_message **ret) {
    2910                 :          8 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
    2911                 :            :         struct reply_callback *c;
    2912                 :            :         int r;
    2913                 :            : 
    2914         [ -  + ]:          8 :         assert(bus);
    2915         [ -  + ]:          8 :         assert(bus->state == BUS_CLOSING);
    2916                 :            : 
    2917                 :            :         /* First, fail all outstanding method calls */
    2918                 :          8 :         c = ordered_hashmap_first(bus->reply_callbacks);
    2919         [ -  + ]:          8 :         if (c)
    2920                 :          0 :                 return process_closing_reply_callback(bus, c);
    2921                 :            : 
    2922                 :            :         /* Then, fake-drop all remaining bus tracking references */
    2923         [ +  + ]:          8 :         if (bus->tracks) {
    2924                 :          4 :                 bus_track_close(bus->tracks);
    2925                 :          4 :                 return 1;
    2926                 :            :         }
    2927                 :            : 
    2928                 :            :         /* Then, synthesize a Disconnected message */
    2929                 :          4 :         r = sd_bus_message_new_signal(
    2930                 :            :                         bus,
    2931                 :            :                         &m,
    2932                 :            :                         "/org/freedesktop/DBus/Local",
    2933                 :            :                         "org.freedesktop.DBus.Local",
    2934                 :            :                         "Disconnected");
    2935         [ -  + ]:          4 :         if (r < 0)
    2936                 :          0 :                 return r;
    2937                 :            : 
    2938                 :          4 :         bus_message_set_sender_local(bus, m);
    2939                 :          4 :         m->read_counter = ++bus->read_counter;
    2940                 :            : 
    2941                 :          4 :         r = bus_seal_synthetic_message(bus, m);
    2942         [ -  + ]:          4 :         if (r < 0)
    2943                 :          0 :                 return r;
    2944                 :            : 
    2945                 :          4 :         sd_bus_close(bus);
    2946                 :            : 
    2947                 :          4 :         bus->current_message = m;
    2948                 :          4 :         bus->iteration_counter++;
    2949                 :            : 
    2950                 :          4 :         r = process_filter(bus, m);
    2951         [ -  + ]:          4 :         if (r != 0)
    2952                 :          0 :                 goto finish;
    2953                 :            : 
    2954                 :          4 :         r = process_match(bus, m);
    2955         [ -  + ]:          4 :         if (r != 0)
    2956                 :          0 :                 goto finish;
    2957                 :            : 
    2958                 :            :         /* Nothing else to do, exit now, if the condition holds */
    2959                 :          4 :         bus->exit_triggered = true;
    2960                 :          4 :         (void) bus_exit_now(bus);
    2961                 :            : 
    2962         [ +  - ]:          4 :         if (ret)
    2963                 :          4 :                 *ret = TAKE_PTR(m);
    2964                 :            : 
    2965                 :          4 :         r = 1;
    2966                 :            : 
    2967                 :          4 : finish:
    2968                 :          4 :         bus->current_message = NULL;
    2969                 :            : 
    2970                 :          4 :         return r;
    2971                 :            : }
    2972                 :            : 
    2973                 :       1070 : static int bus_process_internal(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **ret) {
    2974                 :            :         int r;
    2975                 :            : 
    2976                 :            :         /* Returns 0 when we didn't do anything. This should cause the
    2977                 :            :          * caller to invoke sd_bus_wait() before returning the next
    2978                 :            :          * time. Returns > 0 when we did something, which possibly
    2979                 :            :          * means *ret is filled in with an unprocessed message. */
    2980                 :            : 
    2981   [ -  +  -  + ]:       1070 :         assert_return(bus, -EINVAL);
    2982   [ -  +  -  + ]:       1070 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    2983   [ -  +  -  + ]:       1070 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    2984                 :            : 
    2985                 :            :         /* We don't allow recursively invoking sd_bus_process(). */
    2986   [ -  +  -  + ]:       1070 :         assert_return(!bus->current_message, -EBUSY);
    2987         [ -  + ]:       1070 :         assert(!bus->current_slot); /* This should be NULL whenever bus->current_message is */
    2988                 :            : 
    2989                 :       2140 :         BUS_DONT_DESTROY(bus);
    2990                 :            : 
    2991   [ -  +  +  -  :       1070 :         switch (bus->state) {
             +  +  +  - ]
    2992                 :            : 
    2993                 :          0 :         case BUS_UNSET:
    2994                 :          0 :                 return -ENOTCONN;
    2995                 :            : 
    2996                 :          4 :         case BUS_CLOSED:
    2997                 :          4 :                 return -ECONNRESET;
    2998                 :            : 
    2999                 :         84 :         case BUS_WATCH_BIND:
    3000                 :         84 :                 r = bus_socket_process_watch_bind(bus);
    3001                 :         84 :                 break;
    3002                 :            : 
    3003                 :          0 :         case BUS_OPENING:
    3004                 :          0 :                 r = bus_socket_process_opening(bus);
    3005                 :          0 :                 break;
    3006                 :            : 
    3007                 :        303 :         case BUS_AUTHENTICATING:
    3008                 :        303 :                 r = bus_socket_process_authenticating(bus);
    3009                 :        303 :                 break;
    3010                 :            : 
    3011                 :        671 :         case BUS_RUNNING:
    3012                 :            :         case BUS_HELLO:
    3013                 :        671 :                 r = process_running(bus, hint_priority, priority, ret);
    3014         [ +  + ]:        671 :                 if (r >= 0)
    3015                 :        667 :                         return r;
    3016                 :            : 
    3017                 :            :                 /* This branch initializes *ret, hence we don't use the generic error checking below */
    3018                 :          4 :                 break;
    3019                 :            : 
    3020                 :          8 :         case BUS_CLOSING:
    3021                 :          8 :                 return process_closing(bus, ret);
    3022                 :            : 
    3023                 :          0 :         default:
    3024                 :          0 :                 assert_not_reached("Unknown state");
    3025                 :            :         }
    3026                 :            : 
    3027         [ +  + ]:        391 :         if (ERRNO_IS_DISCONNECT(r)) {
    3028                 :          8 :                 bus_enter_closing(bus);
    3029                 :          8 :                 r = 1;
    3030         [ +  + ]:        383 :         } else if (r < 0)
    3031                 :          4 :                 return r;
    3032                 :            : 
    3033         [ +  + ]:        387 :         if (ret)
    3034                 :         69 :                 *ret = NULL;
    3035                 :            : 
    3036                 :        387 :         return r;
    3037                 :            : }
    3038                 :            : 
    3039                 :       1070 : _public_ int sd_bus_process(sd_bus *bus, sd_bus_message **ret) {
    3040                 :       1070 :         return bus_process_internal(bus, false, 0, ret);
    3041                 :            : }
    3042                 :            : 
    3043                 :          0 : _public_ int sd_bus_process_priority(sd_bus *bus, int64_t priority, sd_bus_message **ret) {
    3044                 :          0 :         return bus_process_internal(bus, true, priority, ret);
    3045                 :            : }
    3046                 :            : 
    3047                 :        459 : static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec) {
    3048                 :        459 :         struct pollfd p[2] = {};
    3049                 :            :         int r, n;
    3050                 :            :         struct timespec ts;
    3051                 :        459 :         usec_t m = USEC_INFINITY;
    3052                 :            : 
    3053         [ -  + ]:        459 :         assert(bus);
    3054                 :            : 
    3055         [ -  + ]:        459 :         if (bus->state == BUS_CLOSING)
    3056                 :          0 :                 return 1;
    3057                 :            : 
    3058         [ -  + ]:        459 :         if (!BUS_IS_OPEN(bus->state))
    3059                 :          0 :                 return -ENOTCONN;
    3060                 :            : 
    3061         [ +  + ]:        459 :         if (bus->state == BUS_WATCH_BIND) {
    3062         [ -  + ]:         24 :                 assert(bus->inotify_fd >= 0);
    3063                 :            : 
    3064                 :         24 :                 p[0].events = POLLIN;
    3065                 :         24 :                 p[0].fd = bus->inotify_fd;
    3066                 :         24 :                 n = 1;
    3067                 :            :         } else {
    3068                 :            :                 int e;
    3069                 :            : 
    3070                 :        435 :                 e = sd_bus_get_events(bus);
    3071         [ -  + ]:        435 :                 if (e < 0)
    3072                 :          0 :                         return e;
    3073                 :            : 
    3074         [ +  + ]:        435 :                 if (need_more)
    3075                 :            :                         /* The caller really needs some more data, he doesn't
    3076                 :            :                          * care about what's already read, or any timeouts
    3077                 :            :                          * except its own. */
    3078                 :        164 :                         e |= POLLIN;
    3079                 :            :                 else {
    3080                 :            :                         usec_t until;
    3081                 :            :                         /* The caller wants to process if there's something to
    3082                 :            :                          * process, but doesn't care otherwise */
    3083                 :            : 
    3084                 :        271 :                         r = sd_bus_get_timeout(bus, &until);
    3085         [ -  + ]:        271 :                         if (r < 0)
    3086                 :          0 :                                 return r;
    3087         [ +  + ]:        271 :                         if (r > 0)
    3088                 :        128 :                                 m = usec_sub_unsigned(until, now(CLOCK_MONOTONIC));
    3089                 :            :                 }
    3090                 :            : 
    3091                 :        435 :                 p[0].fd = bus->input_fd;
    3092         [ +  - ]:        435 :                 if (bus->output_fd == bus->input_fd) {
    3093                 :        435 :                         p[0].events = e;
    3094                 :        435 :                         n = 1;
    3095                 :            :                 } else {
    3096                 :          0 :                         p[0].events = e & POLLIN;
    3097                 :          0 :                         p[1].fd = bus->output_fd;
    3098                 :          0 :                         p[1].events = e & POLLOUT;
    3099                 :          0 :                         n = 2;
    3100                 :            :                 }
    3101                 :            :         }
    3102                 :            : 
    3103   [ +  +  -  +  :        459 :         if (timeout_usec != (uint64_t) -1 && (m == USEC_INFINITY || timeout_usec < m))
                   #  # ]
    3104                 :        164 :                 m = timeout_usec;
    3105                 :            : 
    3106         [ +  + ]:        459 :         r = ppoll(p, n, m == USEC_INFINITY ? NULL : timespec_store(&ts, m), NULL);
    3107         [ -  + ]:        459 :         if (r < 0)
    3108                 :          0 :                 return -errno;
    3109                 :            : 
    3110                 :        459 :         return r > 0 ? 1 : 0;
    3111                 :            : }
    3112                 :            : 
    3113                 :        295 : _public_ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) {
    3114                 :            : 
    3115   [ -  +  -  + ]:        295 :         assert_return(bus, -EINVAL);
    3116   [ -  +  -  + ]:        295 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    3117   [ -  +  -  + ]:        295 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    3118                 :            : 
    3119         [ -  + ]:        295 :         if (bus->state == BUS_CLOSING)
    3120                 :          0 :                 return 0;
    3121                 :            : 
    3122         [ -  + ]:        295 :         if (!BUS_IS_OPEN(bus->state))
    3123                 :          0 :                 return -ENOTCONN;
    3124                 :            : 
    3125         [ -  + ]:        295 :         if (bus->rqueue_size > 0)
    3126                 :          0 :                 return 0;
    3127                 :            : 
    3128                 :        295 :         return bus_poll(bus, false, timeout_usec);
    3129                 :            : }
    3130                 :            : 
    3131                 :        168 : _public_ int sd_bus_flush(sd_bus *bus) {
    3132                 :            :         int r;
    3133                 :            : 
    3134   [ -  +  -  + ]:        168 :         assert_return(bus, -EINVAL);
    3135   [ -  +  -  + ]:        168 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    3136   [ -  +  -  + ]:        168 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    3137                 :            : 
    3138         [ +  + ]:        168 :         if (bus->state == BUS_CLOSING)
    3139                 :          4 :                 return 0;
    3140                 :            : 
    3141         [ +  + ]:        164 :         if (!BUS_IS_OPEN(bus->state))
    3142                 :         20 :                 return -ENOTCONN;
    3143                 :            : 
    3144                 :            :         /* We never were connected? Don't hang in inotify for good, as there's no timeout set for it */
    3145         [ -  + ]:        144 :         if (bus->state == BUS_WATCH_BIND)
    3146                 :          0 :                 return -EUNATCH;
    3147                 :            : 
    3148                 :        144 :         r = bus_ensure_running(bus);
    3149         [ -  + ]:        144 :         if (r < 0)
    3150                 :          0 :                 return r;
    3151                 :            : 
    3152         [ +  - ]:        144 :         if (bus->wqueue_size <= 0)
    3153                 :        144 :                 return 0;
    3154                 :            : 
    3155                 :            :         for (;;) {
    3156                 :          0 :                 r = dispatch_wqueue(bus);
    3157         [ #  # ]:          0 :                 if (r < 0) {
    3158         [ #  # ]:          0 :                         if (ERRNO_IS_DISCONNECT(r)) {
    3159                 :          0 :                                 bus_enter_closing(bus);
    3160                 :          0 :                                 return -ECONNRESET;
    3161                 :            :                         }
    3162                 :            : 
    3163                 :          0 :                         return r;
    3164                 :            :                 }
    3165                 :            : 
    3166         [ #  # ]:          0 :                 if (bus->wqueue_size <= 0)
    3167                 :          0 :                         return 0;
    3168                 :            : 
    3169                 :          0 :                 r = bus_poll(bus, false, (uint64_t) -1);
    3170         [ #  # ]:          0 :                 if (r < 0)
    3171                 :          0 :                         return r;
    3172                 :            :         }
    3173                 :            : }
    3174                 :            : 
    3175                 :          0 : _public_ int sd_bus_add_filter(
    3176                 :            :                 sd_bus *bus,
    3177                 :            :                 sd_bus_slot **slot,
    3178                 :            :                 sd_bus_message_handler_t callback,
    3179                 :            :                 void *userdata) {
    3180                 :            : 
    3181                 :            :         sd_bus_slot *s;
    3182                 :            : 
    3183   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
    3184   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    3185   [ #  #  #  # ]:          0 :         assert_return(callback, -EINVAL);
    3186   [ #  #  #  # ]:          0 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    3187                 :            : 
    3188                 :          0 :         s = bus_slot_allocate(bus, !slot, BUS_FILTER_CALLBACK, sizeof(struct filter_callback), userdata);
    3189         [ #  # ]:          0 :         if (!s)
    3190                 :          0 :                 return -ENOMEM;
    3191                 :            : 
    3192                 :          0 :         s->filter_callback.callback = callback;
    3193                 :            : 
    3194                 :          0 :         bus->filter_callbacks_modified = true;
    3195   [ #  #  #  # ]:          0 :         LIST_PREPEND(callbacks, bus->filter_callbacks, &s->filter_callback);
    3196                 :            : 
    3197         [ #  # ]:          0 :         if (slot)
    3198                 :          0 :                 *slot = s;
    3199                 :            : 
    3200                 :          0 :         return 0;
    3201                 :            : }
    3202                 :            : 
    3203                 :         19 : static int add_match_callback(
    3204                 :            :                 sd_bus_message *m,
    3205                 :            :                 void *userdata,
    3206                 :            :                 sd_bus_error *ret_error) {
    3207                 :            : 
    3208                 :         19 :         sd_bus_slot *match_slot = userdata;
    3209                 :         19 :         bool failed = false;
    3210                 :            :         int r;
    3211                 :            : 
    3212         [ -  + ]:         19 :         assert(m);
    3213         [ -  + ]:         19 :         assert(match_slot);
    3214                 :            : 
    3215                 :         19 :         sd_bus_slot_ref(match_slot);
    3216                 :            : 
    3217         [ -  + ]:         19 :         if (sd_bus_message_is_method_error(m, NULL)) {
    3218         [ #  # ]:          0 :                 log_debug_errno(sd_bus_message_get_errno(m),
    3219                 :            :                                 "Unable to add match %s, failing connection: %s",
    3220                 :            :                                 match_slot->match_callback.match_string,
    3221                 :            :                                 sd_bus_message_get_error(m)->message);
    3222                 :            : 
    3223                 :          0 :                 failed = true;
    3224                 :            :         } else
    3225         [ -  + ]:         19 :                 log_debug("Match %s successfully installed.", match_slot->match_callback.match_string);
    3226                 :            : 
    3227         [ -  + ]:         19 :         if (match_slot->match_callback.install_callback) {
    3228                 :            :                 sd_bus *bus;
    3229                 :            : 
    3230                 :          0 :                 bus = sd_bus_message_get_bus(m);
    3231                 :            : 
    3232                 :            :                 /* This function has been called as slot handler, and we want to call another slot handler. Let's
    3233                 :            :                  * update the slot callback metadata temporarily with our own data, and then revert back to the old
    3234                 :            :                  * values. */
    3235                 :            : 
    3236         [ #  # ]:          0 :                 assert(bus->current_slot == match_slot->match_callback.install_slot);
    3237         [ #  # ]:          0 :                 assert(bus->current_handler == add_match_callback);
    3238         [ #  # ]:          0 :                 assert(bus->current_userdata == userdata);
    3239                 :            : 
    3240                 :          0 :                 bus->current_slot = match_slot;
    3241                 :          0 :                 bus->current_handler = match_slot->match_callback.install_callback;
    3242                 :          0 :                 bus->current_userdata = match_slot->userdata;
    3243                 :            : 
    3244                 :          0 :                 r = match_slot->match_callback.install_callback(m, match_slot->userdata, ret_error);
    3245                 :            : 
    3246                 :          0 :                 bus->current_slot = match_slot->match_callback.install_slot;
    3247                 :          0 :                 bus->current_handler = add_match_callback;
    3248                 :          0 :                 bus->current_userdata = userdata;
    3249                 :            :         } else {
    3250         [ -  + ]:         19 :                 if (failed) /* Generic failure handling: destroy the connection */
    3251                 :          0 :                         bus_enter_closing(sd_bus_message_get_bus(m));
    3252                 :            : 
    3253                 :         19 :                 r = 1;
    3254                 :            :         }
    3255                 :            : 
    3256                 :            :         /* We don't need the install method reply slot anymore, let's free it */
    3257                 :         19 :         match_slot->match_callback.install_slot = sd_bus_slot_unref(match_slot->match_callback.install_slot);
    3258                 :            : 
    3259   [ -  +  #  # ]:         19 :         if (failed && match_slot->floating)
    3260                 :          0 :                 bus_slot_disconnect(match_slot, true);
    3261                 :            : 
    3262                 :         19 :         sd_bus_slot_unref(match_slot);
    3263                 :            : 
    3264                 :         19 :         return r;
    3265                 :            : }
    3266                 :            : 
    3267                 :        120 : static int bus_add_match_full(
    3268                 :            :                 sd_bus *bus,
    3269                 :            :                 sd_bus_slot **slot,
    3270                 :            :                 bool asynchronous,
    3271                 :            :                 const char *match,
    3272                 :            :                 sd_bus_message_handler_t callback,
    3273                 :            :                 sd_bus_message_handler_t install_callback,
    3274                 :            :                 void *userdata) {
    3275                 :            : 
    3276                 :        120 :         struct bus_match_component *components = NULL;
    3277                 :        120 :         unsigned n_components = 0;
    3278                 :        120 :         sd_bus_slot *s = NULL;
    3279                 :        120 :         int r = 0;
    3280                 :            : 
    3281   [ -  +  -  + ]:        120 :         assert_return(bus, -EINVAL);
    3282   [ -  +  -  + ]:        120 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    3283   [ -  +  -  + ]:        120 :         assert_return(match, -EINVAL);
    3284   [ -  +  -  + ]:        120 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    3285                 :            : 
    3286                 :        120 :         r = bus_match_parse(match, &components, &n_components);
    3287         [ -  + ]:        120 :         if (r < 0)
    3288                 :          0 :                 goto finish;
    3289                 :            : 
    3290                 :        120 :         s = bus_slot_allocate(bus, !slot, BUS_MATCH_CALLBACK, sizeof(struct match_callback), userdata);
    3291         [ -  + ]:        120 :         if (!s) {
    3292                 :          0 :                 r = -ENOMEM;
    3293                 :          0 :                 goto finish;
    3294                 :            :         }
    3295                 :            : 
    3296                 :        120 :         s->match_callback.callback = callback;
    3297                 :        120 :         s->match_callback.install_callback = install_callback;
    3298                 :            : 
    3299         [ +  - ]:        120 :         if (bus->bus_client) {
    3300                 :            :                 enum bus_match_scope scope;
    3301                 :            : 
    3302                 :        120 :                 scope = bus_match_get_scope(components, n_components);
    3303                 :            : 
    3304                 :            :                 /* Do not install server-side matches for matches against the local service, interface or bus path. */
    3305         [ +  + ]:        120 :                 if (scope != BUS_MATCH_LOCAL) {
    3306                 :            : 
    3307                 :            :                         /* We store the original match string, so that we can use it to remove the match again. */
    3308                 :            : 
    3309                 :         68 :                         s->match_callback.match_string = strdup(match);
    3310         [ -  + ]:         68 :                         if (!s->match_callback.match_string) {
    3311                 :          0 :                                 r = -ENOMEM;
    3312                 :          0 :                                 goto finish;
    3313                 :            :                         }
    3314                 :            : 
    3315         [ +  + ]:         68 :                         if (asynchronous) {
    3316                 :         60 :                                 r = bus_add_match_internal_async(bus,
    3317                 :            :                                                                  &s->match_callback.install_slot,
    3318                 :         60 :                                                                  s->match_callback.match_string,
    3319                 :            :                                                                  add_match_callback,
    3320                 :            :                                                                  s);
    3321                 :            : 
    3322         [ -  + ]:         60 :                                 if (r < 0)
    3323                 :          0 :                                         return r;
    3324                 :            : 
    3325                 :            :                                 /* Make the slot of the match call floating now. We need the reference, but we don't
    3326                 :            :                                  * want that this match pins the bus object, hence we first create it non-floating, but
    3327                 :            :                                  * then make it floating. */
    3328                 :         60 :                                 r = sd_bus_slot_set_floating(s->match_callback.install_slot, true);
    3329                 :            :                         } else
    3330                 :          8 :                                 r = bus_add_match_internal(bus, s->match_callback.match_string, &s->match_callback.after);
    3331         [ -  + ]:         68 :                         if (r < 0)
    3332                 :          0 :                                 goto finish;
    3333                 :            : 
    3334                 :         68 :                         s->match_added = true;
    3335                 :            :                 }
    3336                 :            :         }
    3337                 :            : 
    3338                 :        120 :         bus->match_callbacks_modified = true;
    3339                 :        120 :         r = bus_match_add(&bus->match_callbacks, components, n_components, &s->match_callback);
    3340         [ -  + ]:        120 :         if (r < 0)
    3341                 :          0 :                 goto finish;
    3342                 :            : 
    3343         [ +  + ]:        120 :         if (slot)
    3344                 :          8 :                 *slot = s;
    3345                 :        120 :         s = NULL;
    3346                 :            : 
    3347                 :        120 : finish:
    3348                 :        120 :         bus_match_parse_free(components, n_components);
    3349                 :        120 :         sd_bus_slot_unref(s);
    3350                 :            : 
    3351                 :        120 :         return r;
    3352                 :            : }
    3353                 :            : 
    3354                 :          8 : _public_ int sd_bus_add_match(
    3355                 :            :                 sd_bus *bus,
    3356                 :            :                 sd_bus_slot **slot,
    3357                 :            :                 const char *match,
    3358                 :            :                 sd_bus_message_handler_t callback,
    3359                 :            :                 void *userdata) {
    3360                 :            : 
    3361                 :          8 :         return bus_add_match_full(bus, slot, false, match, callback, NULL, userdata);
    3362                 :            : }
    3363                 :            : 
    3364                 :        112 : _public_ int sd_bus_add_match_async(
    3365                 :            :                 sd_bus *bus,
    3366                 :            :                 sd_bus_slot **slot,
    3367                 :            :                 const char *match,
    3368                 :            :                 sd_bus_message_handler_t callback,
    3369                 :            :                 sd_bus_message_handler_t install_callback,
    3370                 :            :                 void *userdata) {
    3371                 :            : 
    3372                 :        112 :         return bus_add_match_full(bus, slot, true, match, callback, install_callback, userdata);
    3373                 :            : }
    3374                 :            : 
    3375                 :       5373 : bool bus_pid_changed(sd_bus *bus) {
    3376         [ -  + ]:       5373 :         assert(bus);
    3377                 :            : 
    3378                 :            :         /* We don't support people creating a bus connection and
    3379                 :            :          * keeping it around over a fork(). Let's complain. */
    3380                 :            : 
    3381                 :       5373 :         return bus->original_pid != getpid_cached();
    3382                 :            : }
    3383                 :            : 
    3384                 :        169 : static int io_callback(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
    3385                 :        169 :         sd_bus *bus = userdata;
    3386                 :            :         int r;
    3387                 :            : 
    3388         [ -  + ]:        169 :         assert(bus);
    3389                 :            : 
    3390                 :            :         /* Note that this is called both on input_fd, output_fd as well as inotify_fd events */
    3391                 :            : 
    3392                 :        169 :         r = sd_bus_process(bus, NULL);
    3393         [ -  + ]:        169 :         if (r < 0) {
    3394         [ #  # ]:          0 :                 log_debug_errno(r, "Processing of bus failed, closing down: %m");
    3395                 :          0 :                 bus_enter_closing(bus);
    3396                 :            :         }
    3397                 :            : 
    3398                 :        169 :         return 1;
    3399                 :            : }
    3400                 :            : 
    3401                 :         20 : static int time_callback(sd_event_source *s, uint64_t usec, void *userdata) {
    3402                 :         20 :         sd_bus *bus = userdata;
    3403                 :            :         int r;
    3404                 :            : 
    3405         [ -  + ]:         20 :         assert(bus);
    3406                 :            : 
    3407                 :         20 :         r = sd_bus_process(bus, NULL);
    3408         [ -  + ]:         20 :         if (r < 0) {
    3409         [ #  # ]:          0 :                 log_debug_errno(r, "Processing of bus failed, closing down: %m");
    3410                 :          0 :                 bus_enter_closing(bus);
    3411                 :            :         }
    3412                 :            : 
    3413                 :         20 :         return 1;
    3414                 :            : }
    3415                 :            : 
    3416                 :        231 : static int prepare_callback(sd_event_source *s, void *userdata) {
    3417                 :        231 :         sd_bus *bus = userdata;
    3418                 :            :         int r, e;
    3419                 :            :         usec_t until;
    3420                 :            : 
    3421         [ -  + ]:        231 :         assert(s);
    3422         [ -  + ]:        231 :         assert(bus);
    3423                 :            : 
    3424                 :        231 :         e = sd_bus_get_events(bus);
    3425         [ -  + ]:        231 :         if (e < 0) {
    3426                 :          0 :                 r = e;
    3427                 :          0 :                 goto fail;
    3428                 :            :         }
    3429                 :            : 
    3430         [ -  + ]:        231 :         if (bus->output_fd != bus->input_fd) {
    3431                 :            : 
    3432                 :          0 :                 r = sd_event_source_set_io_events(bus->input_io_event_source, e & POLLIN);
    3433         [ #  # ]:          0 :                 if (r < 0)
    3434                 :          0 :                         goto fail;
    3435                 :            : 
    3436                 :          0 :                 r = sd_event_source_set_io_events(bus->output_io_event_source, e & POLLOUT);
    3437                 :            :         } else
    3438                 :        231 :                 r = sd_event_source_set_io_events(bus->input_io_event_source, e);
    3439         [ -  + ]:        231 :         if (r < 0)
    3440                 :          0 :                 goto fail;
    3441                 :            : 
    3442                 :        231 :         r = sd_bus_get_timeout(bus, &until);
    3443         [ -  + ]:        231 :         if (r < 0)
    3444                 :          0 :                 goto fail;
    3445         [ +  + ]:        231 :         if (r > 0) {
    3446                 :            :                 int j;
    3447                 :            : 
    3448                 :        190 :                 j = sd_event_source_set_time(bus->time_event_source, until);
    3449         [ -  + ]:        190 :                 if (j < 0) {
    3450                 :          0 :                         r = j;
    3451                 :          0 :                         goto fail;
    3452                 :            :                 }
    3453                 :            :         }
    3454                 :            : 
    3455                 :        231 :         r = sd_event_source_set_enabled(bus->time_event_source, r > 0);
    3456         [ -  + ]:        231 :         if (r < 0)
    3457                 :          0 :                 goto fail;
    3458                 :            : 
    3459                 :        231 :         return 1;
    3460                 :            : 
    3461                 :          0 : fail:
    3462         [ #  # ]:          0 :         log_debug_errno(r, "Preparing of bus events failed, closing down: %m");
    3463                 :          0 :         bus_enter_closing(bus);
    3464                 :            : 
    3465                 :          0 :         return 1;
    3466                 :            : }
    3467                 :            : 
    3468                 :         20 : static int quit_callback(sd_event_source *event, void *userdata) {
    3469                 :         20 :         sd_bus *bus = userdata;
    3470                 :            : 
    3471         [ -  + ]:         20 :         assert(event);
    3472                 :            : 
    3473         [ +  - ]:         20 :         if (bus->close_on_exit) {
    3474                 :         20 :                 sd_bus_flush(bus);
    3475                 :         20 :                 sd_bus_close(bus);
    3476                 :            :         }
    3477                 :            : 
    3478                 :         20 :         return 1;
    3479                 :            : }
    3480                 :            : 
    3481                 :        260 : int bus_attach_io_events(sd_bus *bus) {
    3482                 :            :         int r;
    3483                 :            : 
    3484         [ -  + ]:        260 :         assert(bus);
    3485                 :            : 
    3486         [ +  + ]:        260 :         if (bus->input_fd < 0)
    3487                 :         60 :                 return 0;
    3488                 :            : 
    3489         [ +  + ]:        200 :         if (!bus->event)
    3490                 :        124 :                 return 0;
    3491                 :            : 
    3492         [ +  - ]:         76 :         if (!bus->input_io_event_source) {
    3493                 :         76 :                 r = sd_event_add_io(bus->event, &bus->input_io_event_source, bus->input_fd, 0, io_callback, bus);
    3494         [ -  + ]:         76 :                 if (r < 0)
    3495                 :          0 :                         return r;
    3496                 :            : 
    3497                 :         76 :                 r = sd_event_source_set_prepare(bus->input_io_event_source, prepare_callback);
    3498         [ -  + ]:         76 :                 if (r < 0)
    3499                 :          0 :                         return r;
    3500                 :            : 
    3501                 :         76 :                 r = sd_event_source_set_priority(bus->input_io_event_source, bus->event_priority);
    3502         [ -  + ]:         76 :                 if (r < 0)
    3503                 :          0 :                         return r;
    3504                 :            : 
    3505                 :         76 :                 r = sd_event_source_set_description(bus->input_io_event_source, "bus-input");
    3506                 :            :         } else
    3507                 :          0 :                 r = sd_event_source_set_io_fd(bus->input_io_event_source, bus->input_fd);
    3508                 :            : 
    3509         [ -  + ]:         76 :         if (r < 0)
    3510                 :          0 :                 return r;
    3511                 :            : 
    3512         [ -  + ]:         76 :         if (bus->output_fd != bus->input_fd) {
    3513         [ #  # ]:          0 :                 assert(bus->output_fd >= 0);
    3514                 :            : 
    3515         [ #  # ]:          0 :                 if (!bus->output_io_event_source) {
    3516                 :          0 :                         r = sd_event_add_io(bus->event, &bus->output_io_event_source, bus->output_fd, 0, io_callback, bus);
    3517         [ #  # ]:          0 :                         if (r < 0)
    3518                 :          0 :                                 return r;
    3519                 :            : 
    3520                 :          0 :                         r = sd_event_source_set_priority(bus->output_io_event_source, bus->event_priority);
    3521         [ #  # ]:          0 :                         if (r < 0)
    3522                 :          0 :                                 return r;
    3523                 :            : 
    3524                 :          0 :                         r = sd_event_source_set_description(bus->input_io_event_source, "bus-output");
    3525                 :            :                 } else
    3526                 :          0 :                         r = sd_event_source_set_io_fd(bus->output_io_event_source, bus->output_fd);
    3527                 :            : 
    3528         [ #  # ]:          0 :                 if (r < 0)
    3529                 :          0 :                         return r;
    3530                 :            :         }
    3531                 :            : 
    3532                 :         76 :         return 0;
    3533                 :            : }
    3534                 :            : 
    3535                 :        776 : static void bus_detach_io_events(sd_bus *bus) {
    3536         [ -  + ]:        776 :         assert(bus);
    3537                 :            : 
    3538         [ +  + ]:        776 :         if (bus->input_io_event_source) {
    3539                 :         76 :                 sd_event_source_set_enabled(bus->input_io_event_source, SD_EVENT_OFF);
    3540                 :         76 :                 bus->input_io_event_source = sd_event_source_unref(bus->input_io_event_source);
    3541                 :            :         }
    3542                 :            : 
    3543         [ -  + ]:        776 :         if (bus->output_io_event_source) {
    3544                 :          0 :                 sd_event_source_set_enabled(bus->output_io_event_source, SD_EVENT_OFF);
    3545                 :          0 :                 bus->output_io_event_source = sd_event_source_unref(bus->output_io_event_source);
    3546                 :            :         }
    3547                 :        776 : }
    3548                 :            : 
    3549                 :        260 : int bus_attach_inotify_event(sd_bus *bus) {
    3550                 :            :         int r;
    3551                 :            : 
    3552         [ -  + ]:        260 :         assert(bus);
    3553                 :            : 
    3554         [ +  + ]:        260 :         if (bus->inotify_fd < 0)
    3555                 :        204 :                 return 0;
    3556                 :            : 
    3557         [ +  + ]:         56 :         if (!bus->event)
    3558                 :         28 :                 return 0;
    3559                 :            : 
    3560         [ +  + ]:         28 :         if (!bus->inotify_event_source) {
    3561                 :          4 :                 r = sd_event_add_io(bus->event, &bus->inotify_event_source, bus->inotify_fd, EPOLLIN, io_callback, bus);
    3562         [ -  + ]:          4 :                 if (r < 0)
    3563                 :          0 :                         return r;
    3564                 :            : 
    3565                 :          4 :                 r = sd_event_source_set_priority(bus->inotify_event_source, bus->event_priority);
    3566         [ -  + ]:          4 :                 if (r < 0)
    3567                 :          0 :                         return r;
    3568                 :            : 
    3569                 :          4 :                 r = sd_event_source_set_description(bus->inotify_event_source, "bus-inotify");
    3570                 :            :         } else
    3571                 :         24 :                 r = sd_event_source_set_io_fd(bus->inotify_event_source, bus->inotify_fd);
    3572         [ -  + ]:         28 :         if (r < 0)
    3573                 :          0 :                 return r;
    3574                 :            : 
    3575                 :         28 :         return 0;
    3576                 :            : }
    3577                 :            : 
    3578                 :        792 : static void bus_detach_inotify_event(sd_bus *bus) {
    3579         [ -  + ]:        792 :         assert(bus);
    3580                 :            : 
    3581         [ +  + ]:        792 :         if (bus->inotify_event_source) {
    3582                 :          4 :                 sd_event_source_set_enabled(bus->inotify_event_source, SD_EVENT_OFF);
    3583                 :          4 :                 bus->inotify_event_source = sd_event_source_unref(bus->inotify_event_source);
    3584                 :            :         }
    3585                 :        792 : }
    3586                 :            : 
    3587                 :         76 : _public_ int sd_bus_attach_event(sd_bus *bus, sd_event *event, int priority) {
    3588                 :            :         int r;
    3589                 :            : 
    3590   [ -  +  -  + ]:         76 :         assert_return(bus, -EINVAL);
    3591   [ -  +  -  + ]:         76 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    3592   [ -  +  -  + ]:         76 :         assert_return(!bus->event, -EBUSY);
    3593                 :            : 
    3594         [ -  + ]:         76 :         assert(!bus->input_io_event_source);
    3595         [ -  + ]:         76 :         assert(!bus->output_io_event_source);
    3596         [ -  + ]:         76 :         assert(!bus->time_event_source);
    3597                 :            : 
    3598         [ +  - ]:         76 :         if (event)
    3599                 :         76 :                 bus->event = sd_event_ref(event);
    3600                 :            :         else  {
    3601                 :          0 :                 r = sd_event_default(&bus->event);
    3602         [ #  # ]:          0 :                 if (r < 0)
    3603                 :          0 :                         return r;
    3604                 :            :         }
    3605                 :            : 
    3606                 :         76 :         bus->event_priority = priority;
    3607                 :            : 
    3608                 :         76 :         r = sd_event_add_time(bus->event, &bus->time_event_source, CLOCK_MONOTONIC, 0, 0, time_callback, bus);
    3609         [ -  + ]:         76 :         if (r < 0)
    3610                 :          0 :                 goto fail;
    3611                 :            : 
    3612                 :         76 :         r = sd_event_source_set_priority(bus->time_event_source, priority);
    3613         [ -  + ]:         76 :         if (r < 0)
    3614                 :          0 :                 goto fail;
    3615                 :            : 
    3616                 :         76 :         r = sd_event_source_set_description(bus->time_event_source, "bus-time");
    3617         [ -  + ]:         76 :         if (r < 0)
    3618                 :          0 :                 goto fail;
    3619                 :            : 
    3620                 :         76 :         r = sd_event_add_exit(bus->event, &bus->quit_event_source, quit_callback, bus);
    3621         [ -  + ]:         76 :         if (r < 0)
    3622                 :          0 :                 goto fail;
    3623                 :            : 
    3624                 :         76 :         r = sd_event_source_set_description(bus->quit_event_source, "bus-exit");
    3625         [ -  + ]:         76 :         if (r < 0)
    3626                 :          0 :                 goto fail;
    3627                 :            : 
    3628                 :         76 :         r = bus_attach_io_events(bus);
    3629         [ -  + ]:         76 :         if (r < 0)
    3630                 :          0 :                 goto fail;
    3631                 :            : 
    3632                 :         76 :         r = bus_attach_inotify_event(bus);
    3633         [ -  + ]:         76 :         if (r < 0)
    3634                 :          0 :                 goto fail;
    3635                 :            : 
    3636                 :         76 :         return 0;
    3637                 :            : 
    3638                 :          0 : fail:
    3639                 :          0 :         sd_bus_detach_event(bus);
    3640                 :          0 :         return r;
    3641                 :            : }
    3642                 :            : 
    3643                 :        332 : _public_ int sd_bus_detach_event(sd_bus *bus) {
    3644   [ -  +  -  + ]:        332 :         assert_return(bus, -EINVAL);
    3645   [ -  +  -  + ]:        332 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    3646                 :            : 
    3647         [ +  + ]:        332 :         if (!bus->event)
    3648                 :        256 :                 return 0;
    3649                 :            : 
    3650                 :         76 :         bus_detach_io_events(bus);
    3651                 :         76 :         bus_detach_inotify_event(bus);
    3652                 :            : 
    3653         [ +  - ]:         76 :         if (bus->time_event_source) {
    3654                 :         76 :                 sd_event_source_set_enabled(bus->time_event_source, SD_EVENT_OFF);
    3655                 :         76 :                 bus->time_event_source = sd_event_source_unref(bus->time_event_source);
    3656                 :            :         }
    3657                 :            : 
    3658         [ +  - ]:         76 :         if (bus->quit_event_source) {
    3659                 :         76 :                 sd_event_source_set_enabled(bus->quit_event_source, SD_EVENT_OFF);
    3660                 :         76 :                 bus->quit_event_source = sd_event_source_unref(bus->quit_event_source);
    3661                 :            :         }
    3662                 :            : 
    3663                 :         76 :         bus->event = sd_event_unref(bus->event);
    3664                 :         76 :         return 1;
    3665                 :            : }
    3666                 :            : 
    3667                 :         20 : _public_ sd_event* sd_bus_get_event(sd_bus *bus) {
    3668   [ -  +  -  + ]:         20 :         assert_return(bus, NULL);
    3669                 :            : 
    3670                 :         20 :         return bus->event;
    3671                 :            : }
    3672                 :            : 
    3673                 :          0 : _public_ sd_bus_message* sd_bus_get_current_message(sd_bus *bus) {
    3674   [ #  #  #  # ]:          0 :         assert_return(bus, NULL);
    3675                 :            : 
    3676                 :          0 :         return bus->current_message;
    3677                 :            : }
    3678                 :            : 
    3679                 :          0 : _public_ sd_bus_slot* sd_bus_get_current_slot(sd_bus *bus) {
    3680   [ #  #  #  # ]:          0 :         assert_return(bus, NULL);
    3681                 :            : 
    3682                 :          0 :         return bus->current_slot;
    3683                 :            : }
    3684                 :            : 
    3685                 :          0 : _public_ sd_bus_message_handler_t sd_bus_get_current_handler(sd_bus *bus) {
    3686   [ #  #  #  # ]:          0 :         assert_return(bus, NULL);
    3687                 :            : 
    3688                 :          0 :         return bus->current_handler;
    3689                 :            : }
    3690                 :            : 
    3691                 :          0 : _public_ void* sd_bus_get_current_userdata(sd_bus *bus) {
    3692   [ #  #  #  # ]:          0 :         assert_return(bus, NULL);
    3693                 :            : 
    3694                 :          0 :         return bus->current_userdata;
    3695                 :            : }
    3696                 :            : 
    3697                 :          4 : static int bus_default(int (*bus_open)(sd_bus **), sd_bus **default_bus, sd_bus **ret) {
    3698                 :          4 :         sd_bus *b = NULL;
    3699                 :            :         int r;
    3700                 :            : 
    3701         [ -  + ]:          4 :         assert(bus_open);
    3702         [ -  + ]:          4 :         assert(default_bus);
    3703                 :            : 
    3704         [ -  + ]:          4 :         if (!ret)
    3705                 :          0 :                 return !!*default_bus;
    3706                 :            : 
    3707         [ -  + ]:          4 :         if (*default_bus) {
    3708                 :          0 :                 *ret = sd_bus_ref(*default_bus);
    3709                 :          0 :                 return 0;
    3710                 :            :         }
    3711                 :            : 
    3712                 :          4 :         r = bus_open(&b);
    3713         [ -  + ]:          4 :         if (r < 0)
    3714                 :          0 :                 return r;
    3715                 :            : 
    3716                 :          4 :         b->default_bus_ptr = default_bus;
    3717                 :          4 :         b->tid = gettid();
    3718                 :          4 :         *default_bus = b;
    3719                 :            : 
    3720                 :          4 :         *ret = b;
    3721                 :          4 :         return 1;
    3722                 :            : }
    3723                 :            : 
    3724                 :          0 : _public_ int sd_bus_default_system(sd_bus **ret) {
    3725                 :          0 :         return bus_default(sd_bus_open_system, &default_system_bus, ret);
    3726                 :            : }
    3727                 :            : 
    3728                 :          4 : _public_ int sd_bus_default_user(sd_bus **ret) {
    3729                 :          4 :         return bus_default(sd_bus_open_user, &default_user_bus, ret);
    3730                 :            : }
    3731                 :            : 
    3732                 :          0 : _public_ int sd_bus_default(sd_bus **ret) {
    3733                 :          0 :         int (*bus_open)(sd_bus **) = NULL;
    3734                 :            :         sd_bus **busp;
    3735                 :            : 
    3736                 :          0 :         busp = bus_choose_default(&bus_open);
    3737                 :          0 :         return bus_default(bus_open, busp, ret);
    3738                 :            : }
    3739                 :            : 
    3740                 :          0 : _public_ int sd_bus_get_tid(sd_bus *b, pid_t *tid) {
    3741   [ #  #  #  # ]:          0 :         assert_return(b, -EINVAL);
    3742   [ #  #  #  # ]:          0 :         assert_return(tid, -EINVAL);
    3743   [ #  #  #  # ]:          0 :         assert_return(!bus_pid_changed(b), -ECHILD);
    3744                 :            : 
    3745         [ #  # ]:          0 :         if (b->tid != 0) {
    3746                 :          0 :                 *tid = b->tid;
    3747                 :          0 :                 return 0;
    3748                 :            :         }
    3749                 :            : 
    3750         [ #  # ]:          0 :         if (b->event)
    3751                 :          0 :                 return sd_event_get_tid(b->event, tid);
    3752                 :            : 
    3753                 :          0 :         return -ENXIO;
    3754                 :            : }
    3755                 :            : 
    3756                 :         20 : _public_ int sd_bus_path_encode(const char *prefix, const char *external_id, char **ret_path) {
    3757                 :         20 :         _cleanup_free_ char *e = NULL;
    3758                 :            :         char *ret;
    3759                 :            : 
    3760   [ +  +  +  + ]:         20 :         assert_return(object_path_is_valid(prefix), -EINVAL);
    3761   [ -  +  -  + ]:         12 :         assert_return(external_id, -EINVAL);
    3762   [ -  +  -  + ]:         12 :         assert_return(ret_path, -EINVAL);
    3763                 :            : 
    3764                 :         12 :         e = bus_label_escape(external_id);
    3765         [ -  + ]:         12 :         if (!e)
    3766                 :          0 :                 return -ENOMEM;
    3767                 :            : 
    3768                 :         12 :         ret = path_join(prefix, e);
    3769         [ -  + ]:         12 :         if (!ret)
    3770                 :          0 :                 return -ENOMEM;
    3771                 :            : 
    3772                 :         12 :         *ret_path = ret;
    3773                 :         12 :         return 0;
    3774                 :            : }
    3775                 :            : 
    3776                 :         16 : _public_ int sd_bus_path_decode(const char *path, const char *prefix, char **external_id) {
    3777                 :            :         const char *e;
    3778                 :            :         char *ret;
    3779                 :            : 
    3780   [ -  +  -  + ]:         16 :         assert_return(object_path_is_valid(path), -EINVAL);
    3781   [ -  +  -  + ]:         16 :         assert_return(object_path_is_valid(prefix), -EINVAL);
    3782   [ -  +  -  + ]:         16 :         assert_return(external_id, -EINVAL);
    3783                 :            : 
    3784                 :         16 :         e = object_path_startswith(path, prefix);
    3785         [ +  + ]:         16 :         if (!e) {
    3786                 :          4 :                 *external_id = NULL;
    3787                 :          4 :                 return 0;
    3788                 :            :         }
    3789                 :            : 
    3790                 :         12 :         ret = bus_label_unescape(e);
    3791         [ -  + ]:         12 :         if (!ret)
    3792                 :          0 :                 return -ENOMEM;
    3793                 :            : 
    3794                 :         12 :         *external_id = ret;
    3795                 :         12 :         return 1;
    3796                 :            : }
    3797                 :            : 
    3798                 :          4 : _public_ int sd_bus_path_encode_many(char **out, const char *path_template, ...) {
    3799                 :          4 :         _cleanup_strv_free_ char **labels = NULL;
    3800                 :            :         char *path, *path_pos, **label_pos;
    3801                 :            :         const char *sep, *template_pos;
    3802                 :            :         size_t path_length;
    3803                 :            :         va_list list;
    3804                 :            :         int r;
    3805                 :            : 
    3806   [ -  +  -  + ]:          4 :         assert_return(out, -EINVAL);
    3807   [ -  +  -  + ]:          4 :         assert_return(path_template, -EINVAL);
    3808                 :            : 
    3809                 :          4 :         path_length = strlen(path_template);
    3810                 :            : 
    3811                 :          4 :         va_start(list, path_template);
    3812         [ +  + ]:         12 :         for (sep = strchr(path_template, '%'); sep; sep = strchr(sep + 1, '%')) {
    3813                 :            :                 const char *arg;
    3814                 :            :                 char *label;
    3815                 :            : 
    3816                 :          8 :                 arg = va_arg(list, const char *);
    3817         [ -  + ]:          8 :                 if (!arg) {
    3818                 :          0 :                         va_end(list);
    3819                 :          0 :                         return -EINVAL;
    3820                 :            :                 }
    3821                 :            : 
    3822                 :          8 :                 label = bus_label_escape(arg);
    3823         [ -  + ]:          8 :                 if (!label) {
    3824                 :          0 :                         va_end(list);
    3825                 :          0 :                         return -ENOMEM;
    3826                 :            :                 }
    3827                 :            : 
    3828                 :          8 :                 r = strv_consume(&labels, label);
    3829         [ -  + ]:          8 :                 if (r < 0) {
    3830                 :          0 :                         va_end(list);
    3831                 :          0 :                         return r;
    3832                 :            :                 }
    3833                 :            : 
    3834                 :            :                 /* add label length, but account for the format character */
    3835                 :          8 :                 path_length += strlen(label) - 1;
    3836                 :            :         }
    3837                 :          4 :         va_end(list);
    3838                 :            : 
    3839                 :          4 :         path = malloc(path_length + 1);
    3840         [ -  + ]:          4 :         if (!path)
    3841                 :          0 :                 return -ENOMEM;
    3842                 :            : 
    3843                 :          4 :         path_pos = path;
    3844                 :          4 :         label_pos = labels;
    3845                 :            : 
    3846         [ +  - ]:         12 :         for (template_pos = path_template; *template_pos; ) {
    3847                 :         12 :                 sep = strchrnul(template_pos, '%');
    3848                 :         12 :                 path_pos = mempcpy(path_pos, template_pos, sep - template_pos);
    3849         [ +  + ]:         12 :                 if (!*sep)
    3850                 :          4 :                         break;
    3851                 :            : 
    3852                 :          8 :                 path_pos = stpcpy(path_pos, *label_pos++);
    3853                 :          8 :                 template_pos = sep + 1;
    3854                 :            :         }
    3855                 :            : 
    3856                 :          4 :         *path_pos = 0;
    3857                 :          4 :         *out = path;
    3858                 :          4 :         return 0;
    3859                 :            : }
    3860                 :            : 
    3861                 :         88 : _public_ int sd_bus_path_decode_many(const char *path, const char *path_template, ...) {
    3862                 :         88 :         _cleanup_strv_free_ char **labels = NULL;
    3863                 :            :         const char *template_pos, *path_pos;
    3864                 :            :         char **label_pos;
    3865                 :            :         va_list list;
    3866                 :            :         int r;
    3867                 :            : 
    3868                 :            :         /*
    3869                 :            :          * This decodes an object-path based on a template argument. The
    3870                 :            :          * template consists of a verbatim path, optionally including special
    3871                 :            :          * directives:
    3872                 :            :          *
    3873                 :            :          *   - Each occurrence of '%' in the template matches an arbitrary
    3874                 :            :          *     substring of a label in the given path. At most one such
    3875                 :            :          *     directive is allowed per label. For each such directive, the
    3876                 :            :          *     caller must provide an output parameter (char **) via va_arg. If
    3877                 :            :          *     NULL is passed, the given label is verified, but not returned.
    3878                 :            :          *     For each matched label, the *decoded* label is stored in the
    3879                 :            :          *     passed output argument, and the caller is responsible to free
    3880                 :            :          *     it. Note that the output arguments are only modified if the
    3881                 :            :          *     actually path matched the template. Otherwise, they're left
    3882                 :            :          *     untouched.
    3883                 :            :          *
    3884                 :            :          * This function returns <0 on error, 0 if the path does not match the
    3885                 :            :          * template, 1 if it matched.
    3886                 :            :          */
    3887                 :            : 
    3888   [ -  +  -  + ]:         88 :         assert_return(path, -EINVAL);
    3889   [ -  +  -  + ]:         88 :         assert_return(path_template, -EINVAL);
    3890                 :            : 
    3891                 :         88 :         path_pos = path;
    3892                 :            : 
    3893         [ +  + ]:        192 :         for (template_pos = path_template; *template_pos; ) {
    3894                 :            :                 const char *sep;
    3895                 :            :                 size_t length;
    3896                 :            :                 char *label;
    3897                 :            : 
    3898                 :            :                 /* verify everything until the next '%' matches verbatim */
    3899                 :        156 :                 sep = strchrnul(template_pos, '%');
    3900                 :        156 :                 length = sep - template_pos;
    3901         [ +  + ]:        156 :                 if (strncmp(path_pos, template_pos, length))
    3902                 :         16 :                         return 0;
    3903                 :            : 
    3904                 :        140 :                 path_pos += length;
    3905                 :        140 :                 template_pos += length;
    3906                 :            : 
    3907         [ +  + ]:        140 :                 if (!*template_pos)
    3908                 :         32 :                         break;
    3909                 :            : 
    3910                 :            :                 /* We found the next '%' character. Everything up until here
    3911                 :            :                  * matched. We now skip ahead to the end of this label and make
    3912                 :            :                  * sure it matches the tail of the label in the path. Then we
    3913                 :            :                  * decode the string in-between and save it for later use. */
    3914                 :            : 
    3915                 :        108 :                 ++template_pos; /* skip over '%' */
    3916                 :            : 
    3917                 :        108 :                 sep = strchrnul(template_pos, '/');
    3918                 :        108 :                 length = sep - template_pos; /* length of suffix to match verbatim */
    3919                 :            : 
    3920                 :            :                 /* verify the suffixes match */
    3921                 :        108 :                 sep = strchrnul(path_pos, '/');
    3922         [ +  - ]:        108 :                 if (sep - path_pos < (ssize_t)length ||
    3923         [ +  + ]:        108 :                     strncmp(sep - length, template_pos, length))
    3924                 :          4 :                         return 0;
    3925                 :            : 
    3926                 :        104 :                 template_pos += length; /* skip over matched label */
    3927                 :        104 :                 length = sep - path_pos - length; /* length of sub-label to decode */
    3928                 :            : 
    3929                 :            :                 /* store unescaped label for later use */
    3930                 :        104 :                 label = bus_label_unescape_n(path_pos, length);
    3931         [ -  + ]:        104 :                 if (!label)
    3932                 :          0 :                         return -ENOMEM;
    3933                 :            : 
    3934                 :        104 :                 r = strv_consume(&labels, label);
    3935         [ -  + ]:        104 :                 if (r < 0)
    3936                 :          0 :                         return r;
    3937                 :            : 
    3938                 :        104 :                 path_pos = sep; /* skip decoded label and suffix */
    3939                 :            :         }
    3940                 :            : 
    3941                 :            :         /* end of template must match end of path */
    3942         [ +  + ]:         68 :         if (*path_pos)
    3943                 :         36 :                 return 0;
    3944                 :            : 
    3945                 :            :         /* copy the labels over to the caller */
    3946                 :         32 :         va_start(list, path_template);
    3947   [ +  +  +  + ]:         80 :         for (label_pos = labels; label_pos && *label_pos; ++label_pos) {
    3948                 :            :                 char **arg;
    3949                 :            : 
    3950                 :         48 :                 arg = va_arg(list, char **);
    3951         [ +  + ]:         48 :                 if (arg)
    3952                 :         20 :                         *arg = *label_pos;
    3953                 :            :                 else
    3954                 :         28 :                         free(*label_pos);
    3955                 :            :         }
    3956                 :         32 :         va_end(list);
    3957                 :            : 
    3958                 :         32 :         labels = mfree(labels);
    3959                 :         32 :         return 1;
    3960                 :            : }
    3961                 :            : 
    3962                 :          0 : _public_ int sd_bus_try_close(sd_bus *bus) {
    3963   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
    3964   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    3965   [ #  #  #  # ]:          0 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    3966                 :            : 
    3967                 :          0 :         return -EOPNOTSUPP;
    3968                 :            : }
    3969                 :            : 
    3970                 :          4 : _public_ int sd_bus_get_description(sd_bus *bus, const char **description) {
    3971   [ -  +  -  + ]:          4 :         assert_return(bus, -EINVAL);
    3972   [ -  +  -  + ]:          4 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    3973   [ -  +  -  + ]:          4 :         assert_return(description, -EINVAL);
    3974   [ -  +  -  + ]:          4 :         assert_return(bus->description, -ENXIO);
    3975   [ -  +  -  + ]:          4 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    3976                 :            : 
    3977         [ +  - ]:          4 :         if (bus->description)
    3978                 :          4 :                 *description = bus->description;
    3979         [ #  # ]:          0 :         else if (bus->is_system)
    3980                 :          0 :                 *description = "system";
    3981         [ #  # ]:          0 :         else if (bus->is_user)
    3982                 :          0 :                 *description = "user";
    3983                 :            :         else
    3984                 :          0 :                 *description = NULL;
    3985                 :            : 
    3986                 :          4 :         return 0;
    3987                 :            : }
    3988                 :            : 
    3989                 :          0 : _public_ int sd_bus_get_scope(sd_bus *bus, const char **scope) {
    3990   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
    3991   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    3992   [ #  #  #  # ]:          0 :         assert_return(scope, -EINVAL);
    3993   [ #  #  #  # ]:          0 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    3994                 :            : 
    3995         [ #  # ]:          0 :         if (bus->is_user) {
    3996                 :          0 :                 *scope = "user";
    3997                 :          0 :                 return 0;
    3998                 :            :         }
    3999                 :            : 
    4000         [ #  # ]:          0 :         if (bus->is_system) {
    4001                 :          0 :                 *scope = "system";
    4002                 :          0 :                 return 0;
    4003                 :            :         }
    4004                 :            : 
    4005                 :          0 :         return -ENODATA;
    4006                 :            : }
    4007                 :            : 
    4008                 :          0 : _public_ int sd_bus_get_address(sd_bus *bus, const char **address) {
    4009                 :            : 
    4010   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
    4011   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    4012   [ #  #  #  # ]:          0 :         assert_return(address, -EINVAL);
    4013   [ #  #  #  # ]:          0 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    4014                 :            : 
    4015         [ #  # ]:          0 :         if (bus->address) {
    4016                 :          0 :                 *address = bus->address;
    4017                 :          0 :                 return 0;
    4018                 :            :         }
    4019                 :            : 
    4020                 :          0 :         return -ENODATA;
    4021                 :            : }
    4022                 :            : 
    4023                 :          0 : _public_ int sd_bus_get_creds_mask(sd_bus *bus, uint64_t *mask) {
    4024   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
    4025   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    4026   [ #  #  #  # ]:          0 :         assert_return(mask, -EINVAL);
    4027   [ #  #  #  # ]:          0 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    4028                 :            : 
    4029                 :          0 :         *mask = bus->creds_mask;
    4030                 :          0 :         return 0;
    4031                 :            : }
    4032                 :            : 
    4033                 :          0 : _public_ int sd_bus_is_bus_client(sd_bus *bus) {
    4034   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
    4035   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    4036   [ #  #  #  # ]:          0 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    4037                 :            : 
    4038                 :          0 :         return bus->bus_client;
    4039                 :            : }
    4040                 :            : 
    4041                 :          0 : _public_ int sd_bus_is_server(sd_bus *bus) {
    4042   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
    4043   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    4044   [ #  #  #  # ]:          0 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    4045                 :            : 
    4046                 :          0 :         return bus->is_server;
    4047                 :            : }
    4048                 :            : 
    4049                 :          0 : _public_ int sd_bus_is_anonymous(sd_bus *bus) {
    4050   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
    4051   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    4052   [ #  #  #  # ]:          0 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    4053                 :            : 
    4054                 :          0 :         return bus->anonymous_auth;
    4055                 :            : }
    4056                 :            : 
    4057                 :          0 : _public_ int sd_bus_is_trusted(sd_bus *bus) {
    4058   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
    4059   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    4060   [ #  #  #  # ]:          0 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    4061                 :            : 
    4062                 :          0 :         return bus->trusted;
    4063                 :            : }
    4064                 :            : 
    4065                 :          0 : _public_ int sd_bus_is_monitor(sd_bus *bus) {
    4066   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
    4067   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    4068   [ #  #  #  # ]:          0 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    4069                 :            : 
    4070                 :          0 :         return bus->is_monitor;
    4071                 :            : }
    4072                 :            : 
    4073                 :          0 : static void flush_close(sd_bus *bus) {
    4074         [ #  # ]:          0 :         if (!bus)
    4075                 :          0 :                 return;
    4076                 :            : 
    4077                 :            :         /* Flushes and closes the specified bus. We take a ref before,
    4078                 :            :          * to ensure the flushing does not cause the bus to be
    4079                 :            :          * unreferenced. */
    4080                 :            : 
    4081                 :          0 :         sd_bus_flush_close_unref(sd_bus_ref(bus));
    4082                 :            : }
    4083                 :            : 
    4084                 :          0 : _public_ void sd_bus_default_flush_close(void) {
    4085                 :          0 :         flush_close(default_starter_bus);
    4086                 :          0 :         flush_close(default_user_bus);
    4087                 :          0 :         flush_close(default_system_bus);
    4088                 :          0 : }
    4089                 :            : 
    4090                 :          0 : _public_ int sd_bus_set_exit_on_disconnect(sd_bus *bus, int b) {
    4091   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
    4092   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    4093                 :            : 
    4094                 :            :         /* Turns on exit-on-disconnect, and triggers it immediately if the bus connection was already
    4095                 :            :          * disconnected. Note that this is triggered exclusively on disconnections triggered by the server side, never
    4096                 :            :          * from the client side. */
    4097                 :          0 :         bus->exit_on_disconnect = b;
    4098                 :            : 
    4099                 :            :         /* If the exit condition was triggered already, exit immediately. */
    4100                 :          0 :         return bus_exit_now(bus);
    4101                 :            : }
    4102                 :            : 
    4103                 :          0 : _public_ int sd_bus_get_exit_on_disconnect(sd_bus *bus) {
    4104   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
    4105   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    4106                 :            : 
    4107                 :          0 :         return bus->exit_on_disconnect;
    4108                 :            : }
    4109                 :            : 
    4110                 :          0 : _public_ int sd_bus_set_sender(sd_bus *bus, const char *sender) {
    4111   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
    4112   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    4113   [ #  #  #  # ]:          0 :         assert_return(!bus->bus_client, -EPERM);
    4114   [ #  #  #  #  :          0 :         assert_return(!sender || service_name_is_valid(sender), -EINVAL);
                   #  # ]
    4115                 :            : 
    4116                 :          0 :         return free_and_strdup(&bus->patch_sender, sender);
    4117                 :            : }
    4118                 :            : 
    4119                 :          0 : _public_ int sd_bus_get_sender(sd_bus *bus, const char **ret) {
    4120   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
    4121   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    4122   [ #  #  #  # ]:          0 :         assert_return(ret, -EINVAL);
    4123                 :            : 
    4124         [ #  # ]:          0 :         if (!bus->patch_sender)
    4125                 :          0 :                 return -ENODATA;
    4126                 :            : 
    4127                 :          0 :         *ret = bus->patch_sender;
    4128                 :          0 :         return 0;
    4129                 :            : }
    4130                 :            : 
    4131                 :          0 : _public_ int sd_bus_get_n_queued_read(sd_bus *bus, uint64_t *ret) {
    4132   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
    4133   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    4134   [ #  #  #  # ]:          0 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    4135   [ #  #  #  # ]:          0 :         assert_return(ret, -EINVAL);
    4136                 :            : 
    4137                 :          0 :         *ret = bus->rqueue_size;
    4138                 :          0 :         return 0;
    4139                 :            : }
    4140                 :            : 
    4141                 :          0 : _public_ int sd_bus_get_n_queued_write(sd_bus *bus, uint64_t *ret) {
    4142   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
    4143   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    4144   [ #  #  #  # ]:          0 :         assert_return(!bus_pid_changed(bus), -ECHILD);
    4145   [ #  #  #  # ]:          0 :         assert_return(ret, -EINVAL);
    4146                 :            : 
    4147                 :          0 :         *ret = bus->wqueue_size;
    4148                 :          0 :         return 0;
    4149                 :            : }
    4150                 :            : 
    4151                 :          0 : _public_ int sd_bus_set_method_call_timeout(sd_bus *bus, uint64_t usec) {
    4152   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
    4153   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    4154                 :            : 
    4155                 :          0 :         bus->method_call_timeout = usec;
    4156                 :          0 :         return 0;
    4157                 :            : }
    4158                 :            : 
    4159                 :        552 : _public_ int sd_bus_get_method_call_timeout(sd_bus *bus, uint64_t *ret) {
    4160                 :            :         const char *e;
    4161                 :            :         usec_t usec;
    4162                 :            : 
    4163   [ -  +  -  + ]:        552 :         assert_return(bus, -EINVAL);
    4164   [ -  +  -  + ]:        552 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    4165   [ -  +  -  + ]:        552 :         assert_return(ret, -EINVAL);
    4166                 :            : 
    4167         [ +  + ]:        552 :         if (bus->method_call_timeout != 0) {
    4168                 :        364 :                 *ret = bus->method_call_timeout;
    4169                 :        364 :                 return 0;
    4170                 :            :         }
    4171                 :            : 
    4172                 :        188 :         e = secure_getenv("SYSTEMD_BUS_TIMEOUT");
    4173   [ -  +  #  #  :        188 :         if (e && parse_sec(e, &usec) >= 0 && usec != 0) {
                   #  # ]
    4174                 :            :                 /* Save the parsed value to avoid multiple parsing. To change the timeout value,
    4175                 :            :                  * use sd_bus_set_method_call_timeout() instead of setenv(). */
    4176                 :          0 :                 *ret = bus->method_call_timeout = usec;
    4177                 :          0 :                 return 0;
    4178                 :            :         }
    4179                 :            : 
    4180                 :        188 :         *ret = bus->method_call_timeout = BUS_DEFAULT_TIMEOUT;
    4181                 :        188 :         return 0;
    4182                 :            : }
    4183                 :            : 
    4184                 :          0 : _public_ int sd_bus_set_close_on_exit(sd_bus *bus, int b) {
    4185   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
    4186   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    4187                 :            : 
    4188                 :          0 :         bus->close_on_exit = b;
    4189                 :          0 :         return 0;
    4190                 :            : }
    4191                 :            : 
    4192                 :          0 : _public_ int sd_bus_get_close_on_exit(sd_bus *bus) {
    4193   [ #  #  #  # ]:          0 :         assert_return(bus, -EINVAL);
    4194   [ #  #  #  # ]:          0 :         assert_return(bus = bus_resolve(bus), -ENOPKG);
    4195                 :            : 
    4196                 :          0 :         return bus->close_on_exit;
    4197                 :            : }

Generated by: LCOV version 1.14