summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-01-26 19:49:08 +0100
committerLennart Poettering <lennart@poettering.net>2016-01-27 02:21:28 +0100
commit1b53f64b001d2a8acb398eb8d546ec4570c1f235 (patch)
tree7f54bb17c34527f741ffa92d61f1264c4b5aed2c
parent218685865a3a7457cb220d20b8f339618cd1d488 (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.
-rw-r--r--src/systemctl/systemctl.c15
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;