X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd-bus%2Fbus-message.c;h=760a148fadd8f473f110d0a06589d8cdb4255cea;hb=2a0e0692565f0435657c93498e09cbb2d3517152;hp=dbb33376192eb2a41b4537b3980316d17e9c125b;hpb=5cbe749238f62546f70d81173a2778f3982adb03;p=elogind.git diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c index dbb333761..760a148fa 100644 --- a/src/libsystemd-bus/bus-message.c +++ b/src/libsystemd-bus/bus-message.c @@ -65,8 +65,8 @@ static void message_free_part(sd_bus_message *m, struct bus_body_part *part) { if (!part->sealed) bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped); else { - if (part->size > 0) - assert_se(munmap(part->data, PAGE_ALIGN(part->size)) == 0); + if (part->mapped > 0) + assert_se(munmap(part->data, part->mapped) == 0); close_nointr_nofail(part->memfd); } @@ -125,17 +125,21 @@ static void message_free(sd_bus_message *m) { if (m->free_kdbus) free(m->kdbus); - if (m->release_kdbus) - ioctl(m->bus->input_fd, KDBUS_CMD_MSG_RELEASE, m->kdbus); + if (m->release_kdbus) { + uint64_t off; - if (m->free_fds) { - close_many(m->fds, m->n_fds); - free(m->fds); + off = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer; + ioctl(m->bus->input_fd, KDBUS_CMD_MSG_RELEASE, &off); } if (m->bus) sd_bus_unref(m->bus); + if (m->free_fds) { + close_many(m->fds, m->n_fds); + free(m->fds); + } + if (m->iovec != m->iovec_fixed) free(m->iovec); @@ -564,7 +568,7 @@ static int message_new_reply( goto fail; if (call->sender) { - r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender); + r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination); if (r < 0) goto fail; } @@ -623,6 +627,43 @@ fail: return r; } +int bus_message_new_synthetic_error( + sd_bus *bus, + uint64_t serial, + const sd_bus_error *e, + sd_bus_message **m) { + + sd_bus_message *t; + int r; + + assert(sd_bus_error_is_set(e)); + assert(m); + + t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_ERROR); + if (!t) + return -ENOMEM; + + t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED; + t->reply_serial = serial; + + r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial); + if (r < 0) + goto fail; + + if (bus && bus->unique_name) { + r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination); + if (r < 0) + goto fail; + } + + *m = t; + return 0; + +fail: + message_free(t); + return r; +} + sd_bus_message* sd_bus_message_ref(sd_bus_message *m) { if (!m) return NULL; @@ -1175,8 +1216,9 @@ static int part_make_space( part->mapped = psz; part->data = n; - part->munmap_this = true; } + + part->munmap_this = true; } else { n = realloc(part->data, sz); if (!n) { @@ -1207,7 +1249,6 @@ static void message_extend_containers(sd_bus_message *m, size_t expand) { for (c = m->containers; c < m->containers + m->n_containers; c++) if (c->array_size) *c->array_size += expand; - } static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) { @@ -3828,9 +3869,9 @@ int bus_message_seal(sd_bus_message *m, uint64_t serial) { /* If this is something we can send as memfd, then let's seal the memfd now. Note that we can send memfds as payload only for directed messages, and not for broadcasts. */ - if (m->destination) { + if (m->destination && m->bus && m->bus->use_memfd) { MESSAGE_FOREACH_PART(part, i, m) - if (part->memfd >= 0 && !part->sealed && part->size > MEMFD_MIN_SIZE) { + if (part->memfd >= 0 && !part->sealed && (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0)) { bus_body_part_unmap(part); if (ioctl(part->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) >= 0) @@ -4240,3 +4281,12 @@ int bus_header_message_size(struct bus_header *h, size_t *sum) { *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs; return 0; } + +int bus_message_to_errno(sd_bus_message *m) { + assert(m); + + if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR) + return 0; + + return bus_error_to_errno(&m->error); +}