- bus_free(bus);
-
- return NULL;
-}
-
-int sd_bus_is_open(sd_bus *bus) {
- if (!bus)
- return -EINVAL;
-
- return bus->fd >= 0;
-}
-
-int sd_bus_can_send(sd_bus *bus, char type) {
- int r;
-
- if (!bus)
- return -EINVAL;
-
- if (type == SD_BUS_TYPE_UNIX_FD) {
- r = bus_ensure_running(bus);
- if (r < 0)
- return r;
-
- return bus->can_fds;
- }
-
- return bus_type_is_valid(type);
-}
-
-int sd_bus_get_peer(sd_bus *bus, sd_id128_t *peer) {
- int r;
-
- if (!bus)
- return -EINVAL;
- if (!peer)
- return -EINVAL;
-
- r = bus_ensure_running(bus);
- if (r < 0)
- return r;
-
- *peer = bus->peer;
- return 0;
-}
-
-static int bus_seal_message(sd_bus *b, sd_bus_message *m) {
- assert(m);
-
- if (m->header->version > b->message_version)
- return -EPERM;
-
- if (m->sealed)
- return 0;
-
- return bus_message_seal(m, ++b->serial);
-}
-
-static int message_write(sd_bus *bus, sd_bus_message *m, size_t *idx) {
- struct msghdr mh;
- struct iovec *iov;
- ssize_t k;
- size_t n;
- unsigned j;
-
- assert(bus);
- assert(m);
- assert(idx);
- assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
-
- if (*idx >= m->size)
- return 0;
-
- n = m->n_iovec * sizeof(struct iovec);
- iov = alloca(n);
- memcpy(iov, m->iovec, n);
-
- j = 0;
- iovec_advance(iov, &j, *idx);
-
- zero(mh);
- mh.msg_iov = iov;
- mh.msg_iovlen = m->n_iovec;
-
- k = sendmsg(bus->fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
- if (k < 0)
- return errno == EAGAIN ? 0 : -errno;
-
- *idx += (size_t) k;
- return 1;
-}
-
-static int message_read_need(sd_bus *bus, size_t *need) {
- uint32_t a, b;
- uint8_t e;
- uint64_t sum;
-
- assert(bus);
- assert(need);
- assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
-
- if (bus->rbuffer_size < sizeof(struct bus_header)) {
- *need = sizeof(struct bus_header) + 8;
-
- /* Minimum message size:
- *
- * Header +
- *
- * Method Call: +2 string headers
- * Signal: +3 string headers
- * Method Error: +1 string headers
- * +1 uint32 headers
- * Method Reply: +1 uint32 headers
- *
- * A string header is at least 9 bytes
- * A uint32 header is at least 8 bytes
- *
- * Hence the minimum message size of a valid message
- * is header + 8 bytes */
-
- return 0;
- }
-
- a = ((const uint32_t*) bus->rbuffer)[1];
- b = ((const uint32_t*) bus->rbuffer)[3];
-
- e = ((const uint8_t*) bus->rbuffer)[0];
- if (e == SD_BUS_LITTLE_ENDIAN) {
- a = le32toh(a);
- b = le32toh(b);
- } else if (e == SD_BUS_BIG_ENDIAN) {
- a = be32toh(a);
- b = be32toh(b);
- } else
- return -EBADMSG;
-
- sum = (uint64_t) sizeof(struct bus_header) + (uint64_t) ALIGN_TO(b, 8) + (uint64_t) a;
- if (sum >= BUS_MESSAGE_SIZE_MAX)
- return -ENOBUFS;
-
- *need = (size_t) sum;
- return 0;
-}
-
-static int message_make(sd_bus *bus, size_t size, sd_bus_message **m) {
- sd_bus_message *t;
- void *b = NULL;
- int r;
-
- assert(bus);
- assert(m);
- assert(bus->rbuffer_size >= size);
- assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
-
- if (bus->rbuffer_size > size) {
- b = memdup((const uint8_t*) bus->rbuffer + size,
- bus->rbuffer_size - size);
- if (!b)
- return -ENOMEM;
- }
-
- r = bus_message_from_malloc(bus->rbuffer, size,
- bus->ucred_valid ? &bus->ucred : NULL,
- bus->label[0] ? bus->label : NULL, &t);
- if (r < 0) {
- free(b);
- return r;
- }
-
- bus->rbuffer = b;
- bus->rbuffer_size -= size;
-
- *m = t;
- return 1;
-}
-
-static int message_read(sd_bus *bus, sd_bus_message **m) {
- struct msghdr mh;
- struct iovec iov;
- ssize_t k;
- size_t need;
- int r;
- void *b;
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(struct ucred)) +
- CMSG_SPACE(NAME_MAX)]; /*selinux label */
- } control;
- struct cmsghdr *cmsg;
-
- assert(bus);
- assert(m);
- assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO);
-
- r = message_read_need(bus, &need);
- if (r < 0)
- return r;