diff options
author | Lennart Poettering <lennart@poettering.net> | 2016-01-26 19:49:08 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2016-01-27 02:21:28 +0100 |
commit | 1b53f64b001d2a8acb398eb8d546ec4570c1f235 (patch) | |
tree | 7f54bb17c34527f741ffa92d61f1264c4b5aed2c /src/systemctl/systemctl.c | |
parent | 218685865a3a7457cb220d20b8f339618cd1d488 (diff) |
systemctl: piece-meal strv extension is expensive
If we have many entries to add to an strv we really should try to be smarter than constantly realloc()ing the strv
array. Instead, grow it exponentially.
Diffstat (limited to 'src/systemctl/systemctl.c')
-rw-r--r-- | src/systemctl/systemctl.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 94c99c4d91..73f5710b9c 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -2658,14 +2658,25 @@ static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***r if (!strv_isempty(globs)) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; _cleanup_free_ UnitInfo *unit_infos = NULL; + size_t allocated, n; r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply); if (r < 0) return r; - for (i = 0; i < r; i++) - if (strv_extend(&mangled, unit_infos[i].id) < 0) + n = strv_length(mangled); + allocated = n + 1; + + for (i = 0; i < r; i++) { + if (!GREEDY_REALLOC(mangled, allocated, n+2)) + return log_oom(); + + mangled[n] = strdup(unit_infos[i].id); + if (!mangled[n]) return log_oom(); + + mangled[++n] = NULL; + } } *ret = mangled; |