X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flibsystemd-bus%2Fbus-socket.c;h=5e285c9e528ed669c3904f5a91041261391bd92d;hp=1a0d9266f2727bc2eb9cc9c4934b47824319ca55;hb=2100fa1099b086411270a2876dde0532ea2806fa;hpb=9be9c7cff600018279a0c3fa5fbe719bd1c0b8ad diff --git a/src/libsystemd-bus/bus-socket.c b/src/libsystemd-bus/bus-socket.c index 1a0d9266f..5e285c9e5 100644 --- a/src/libsystemd-bus/bus-socket.c +++ b/src/libsystemd-bus/bus-socket.c @@ -58,6 +58,39 @@ static void iovec_advance(struct iovec iov[], unsigned *idx, size_t size) { } } +static void 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++; +} + +static void bus_message_setup_iovec(sd_bus_message *m) { + assert(m); + assert(m->sealed); + + if (m->n_iovec > 0) + return; + + append_iovec(m, m->header, sizeof(*m->header)); + + if (m->fields) { + append_iovec(m, m->fields, m->header->fields_size); + + if (m->header->fields_size % 8 != 0) { + static const uint8_t padding[7] = {}; + + append_iovec(m, padding, 8 - (m->header->fields_size % 8)); + } + } + + if (m->body) + append_iovec(m, m->body, m->header->body_size); +} + bool bus_socket_auth_needs_write(sd_bus *b) { unsigned i; @@ -729,9 +762,11 @@ int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) { assert(idx); assert(bus->state == BUS_RUNNING || bus->state == BUS_HELLO); - if (*idx >= m->size) + if (*idx >= bus_message_size(m)) return 0; + bus_message_setup_iovec(m); + n = m->n_iovec * sizeof(struct iovec); iov = alloca(n); memcpy(iov, m->iovec, n);