X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flibsystemd%2Fsd-bus%2Fbus-kernel.c;h=aaf44e3e758fc8b589593babbaf30ce0ace27a93;hp=5b4bbfd1ea022e81febb01a2ecc9bdf1e8ba1168;hb=1abe54d9a9292d746e5990843bbbc509984b7f2c;hpb=da927ba997d68401563b927f92e6e40e021a8e5c diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c index 5b4bbfd1e..aaf44e3e7 100644 --- a/src/libsystemd/sd-bus/bus-kernel.c +++ b/src/libsystemd/sd-bus/bus-kernel.c @@ -135,6 +135,32 @@ static void append_fds(struct kdbus_item **d, const int fds[], unsigned n_fds) { *d = (struct kdbus_item *) ((uint8_t*) *d + (*d)->size); } +static void add_bloom_arg(void *data, size_t size, unsigned n_hash, unsigned i, const char *t) { + char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")]; + char *e; + + assert(data); + assert(size > 0); + assert(i < 64); + assert(t); + + e = stpcpy(buf, "arg"); + if (i < 10) + *(e++) = '0' + (char) i; + else { + *(e++) = '0' + (char) (i / 10); + *(e++) = '0' + (char) (i % 10); + } + + *e = 0; + bloom_add_pair(data, size, n_hash, buf, t); + + strcpy(e, "-dot-prefix"); + bloom_add_prefixes(data, size, n_hash, buf, t, '.'); + strcpy(e, "-slash-prefix"); + bloom_add_prefixes(data, size, n_hash, buf, t, '/'); +} + static int bus_message_setup_bloom(sd_bus_message *m, struct kdbus_bloom_filter *bloom) { void *data; unsigned i; @@ -164,39 +190,42 @@ static int bus_message_setup_bloom(sd_bus_message *m, struct kdbus_bloom_filter return r; for (i = 0; i < 64; i++) { + const char *t, *contents; char type; - const char *t; - char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")]; - char *e; - r = sd_bus_message_peek_type(m, &type, NULL); + r = sd_bus_message_peek_type(m, &type, &contents); if (r < 0) return r; - if (type != SD_BUS_TYPE_STRING && - type != SD_BUS_TYPE_OBJECT_PATH && - type != SD_BUS_TYPE_SIGNATURE) - break; + if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) { - r = sd_bus_message_read_basic(m, type, &t); - if (r < 0) - return r; + /* The bloom filter includes simple strings of any kind */ + r = sd_bus_message_read_basic(m, type, &t); + if (r < 0) + return r; - e = stpcpy(buf, "arg"); - if (i < 10) - *(e++) = '0' + (char) i; - else { - *(e++) = '0' + (char) (i / 10); - *(e++) = '0' + (char) (i % 10); - } + add_bloom_arg(data, m->bus->bloom_size, m->bus->bloom_n_hash, i, t); + } if (type == SD_BUS_TYPE_ARRAY && STR_IN_SET(contents, "s", "o", "g")) { - *e = 0; - bloom_add_pair(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t); + /* As well as array of simple strings of any kinds */ + r = sd_bus_message_enter_container(m, type, contents); + if (r < 0) + return r; + + while ((r = sd_bus_message_read_basic(m, contents[0], &t)) > 0) + add_bloom_arg(data, m->bus->bloom_size, m->bus->bloom_n_hash, i, t); + if (r < 0) + return r; - strcpy(e, "-dot-prefix"); - bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t, '.'); - strcpy(e, "-slash-prefix"); - bloom_add_prefixes(data, m->bus->bloom_size, m->bus->bloom_n_hash, buf, t, '/'); + r = sd_bus_message_exit_container(m); + if (r < 0) + return r; + + } else + /* Stop adding to bloom filter as soon as we + * run into the first argument we cannot add + * to it. */ + break; } return 0; @@ -954,24 +983,37 @@ int bus_kernel_connect(sd_bus *b) { return bus_kernel_take_fd(b); } +int bus_kernel_cmd_free(sd_bus *bus, uint64_t offset) { + struct kdbus_cmd_free cmd = { + .flags = 0, + .offset = offset, + }; + int r; + + assert(bus); + assert(bus->is_kernel); + + r = ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd); + if (r < 0) + return -errno; + + return 0; +} + static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) { - struct kdbus_cmd_free cmd = {}; struct kdbus_item *d; assert(bus); assert(k); - cmd.offset = (uint8_t *)k - (uint8_t *)bus->kdbus_buffer; - KDBUS_ITEM_FOREACH(d, k, items) { - if (d->type == KDBUS_ITEM_FDS) close_many(d->fds, (d->size - offsetof(struct kdbus_item, fds)) / sizeof(int)); else if (d->type == KDBUS_ITEM_PAYLOAD_MEMFD) safe_close(d->memfd.fd); } - (void) ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd); + bus_kernel_cmd_free(bus, (uint8_t*) k - (uint8_t*) bus->kdbus_buffer); } int bus_kernel_write_message(sd_bus *bus, sd_bus_message *m, bool hint_sync_call) { @@ -1832,3 +1874,39 @@ int bus_kernel_fix_attach_mask(void) { return 0; } + +int bus_kernel_get_bus_name(sd_bus *bus, char **name) { + struct kdbus_cmd_info cmd = { + .size = sizeof(struct kdbus_cmd_info), + }; + struct kdbus_info *info; + struct kdbus_item *item; + char *n = NULL; + int r; + + assert(bus); + assert(name); + assert(bus->is_kernel); + + r = ioctl(bus->input_fd, KDBUS_CMD_BUS_CREATOR_INFO, &cmd); + if (r < 0) + return -errno; + + info = (struct kdbus_info*) ((uint8_t*) bus->kdbus_buffer + cmd.offset); + + KDBUS_ITEM_FOREACH(item, info, items) + if (item->type == KDBUS_ITEM_MAKE_NAME) { + r = free_and_strdup(&n, item->str); + break; + } + + bus_kernel_cmd_free(bus, cmd.offset); + + if (r < 0) + return r; + if (!n) + return -EIO; + + *name = n; + return 0; +}