X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd-bus%2Fbus-socket.c;h=4635da4b9ea436d98ee6735fb7cc5be5a12f80a4;hb=c91cb83c4dbc9a95a0a2a38e7028e0a7f4af3b35;hp=c68c7bca682791625b4adf05a50833fb75ad0f49;hpb=9607d9470eec07df817e58f64d312ccb5ac4cfcc;p=elogind.git diff --git a/src/libsystemd-bus/bus-socket.c b/src/libsystemd-bus/bus-socket.c index c68c7bca6..4635da4b9 100644 --- a/src/libsystemd-bus/bus-socket.c +++ b/src/libsystemd-bus/bus-socket.c @@ -58,6 +58,55 @@ static void iovec_advance(struct iovec iov[], unsigned *idx, size_t size) { } } +static int append_iovec(sd_bus_message *m, const void *p, size_t sz) { + assert(m); + assert(p); + assert(sz > 0); + + m->iovec[m->n_iovec].iov_base = (void*) p; + m->iovec[m->n_iovec].iov_len = sz; + m->n_iovec++; + + return 0; +} + +static int bus_message_setup_iovec(sd_bus_message *m) { + struct bus_body_part *part; + unsigned n, i; + int r; + + assert(m); + assert(m->sealed); + + if (m->n_iovec > 0) + return 0; + + assert(!m->iovec); + + n = 1 + m->n_body_parts; + if (n < ELEMENTSOF(m->iovec_fixed)) + m->iovec = m->iovec_fixed; + else { + m->iovec = new(struct iovec, n); + if (!m->iovec) + return -ENOMEM; + } + + r = append_iovec(m, m->header, BUS_MESSAGE_BODY_BEGIN(m)); + if (r < 0) + return r; + + MESSAGE_FOREACH_PART(part, i, m) { + r = append_iovec(m, part->data, part->size); + if (r < 0) + return r; + } + + assert(n == m->n_iovec); + + return 0; +} + bool bus_socket_auth_needs_write(sd_bus *b) { unsigned i; @@ -723,15 +772,20 @@ int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) { ssize_t k; size_t n; unsigned j; + int r; assert(bus); assert(m); assert(idx); assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO); - if (*idx >= m->size) + if (*idx >= BUS_MESSAGE_SIZE(m)) return 0; + r = bus_message_setup_iovec(m); + if (r < 0) + return r; + n = m->n_iovec * sizeof(struct iovec); iov = alloca(n); memcpy(iov, m->iovec, n); @@ -877,7 +931,7 @@ int bus_socket_read_message(sd_bus *bus, sd_bus_message **m) { CMSG_SPACE(NAME_MAX)]; /*selinux label */ } control; struct cmsghdr *cmsg; - bool handle_cmsg; + bool handle_cmsg = false; assert(bus); assert(m); @@ -986,16 +1040,14 @@ int bus_socket_read_message(sd_bus *bus, sd_bus_message **m) { int bus_socket_process_opening(sd_bus *b) { int error = 0; socklen_t slen = sizeof(error); - struct pollfd p; + struct pollfd p = { + .fd = b->output_fd, + .events = POLLOUT, + }; int r; - assert(b); assert(b->state == BUS_OPENING); - zero(p); - p.fd = b->output_fd; - p.events = POLLOUT; - r = poll(&p, 1, 0); if (r < 0) return -errno;