From: Lennart Poettering Date: Thu, 27 Nov 2014 01:28:23 +0000 (+0100) Subject: sd-bus: optimize how we generate the well-known-names lists in messages from kdbus X-Git-Tag: v218~294 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=50c4521675e94ade38b8af9e3b0f7fd2f300b6f4 sd-bus: optimize how we generate the well-known-names lists in messages from kdbus --- diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c index 8aa53362f..ad0e2e1ba 100644 --- a/src/libsystemd/sd-bus/bus-creds.c +++ b/src/libsystemd/sd-bus/bus-creds.c @@ -51,8 +51,14 @@ void bus_creds_done(sd_bus_creds *c) { free(c->slice); free(c->unescaped_description); + free(c->well_known_names); /* note that this is an strv, but + * we only free the array, not the + * strings the array points to. The + * full strv we only free if + * c->allocated is set, see + * below. */ + strv_free(c->cmdline_array); - strv_free(c->well_known_names); } _public_ sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c) { @@ -83,8 +89,6 @@ _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) { c->n_ref--; if (c->n_ref == 0) { - bus_creds_done(c); - free(c->comm); free(c->tid_comm); free(c->exe); @@ -96,6 +100,12 @@ _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) { free(c->cgroup_root); free(c->description); free(c->supplementary_gids); + + strv_free(c->well_known_names); + c->well_known_names = NULL; + + bus_creds_done(c); + free(c); } } else { diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c index ef157d69f..1276cd841 100644 --- a/src/libsystemd/sd-bus/bus-kernel.c +++ b/src/libsystemd/sd-bus/bus-kernel.c @@ -660,9 +660,23 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) { } if (bus->creds_mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) { - r = strv_extend(&m->creds.well_known_names, d->name.name); - if (r < 0) + char **wkn; + size_t n; + + /* We just extend the array here, but + * do not allocate the strings inside + * of it, instead we just point to our + * buffer directly. */ + n = strv_length(m->creds.well_known_names); + wkn = realloc(m->creds.well_known_names, (n + 2) * sizeof(char*)); + if (!wkn) { + r = -ENOMEM; goto fail; + } + + wkn[n] = d->name.name; + wkn[n+1] = NULL; + m->creds.well_known_names = wkn; m->creds.mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES; }