summaryrefslogtreecommitdiff
path: root/src/systemctl/systemctl.c
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 /src/systemctl/systemctl.c
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.
Diffstat (limited to 'src/systemctl/systemctl.c')
-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;