From: Lennart Poettering Date: Wed, 23 Aug 2023 12:29:40 +0000 (+0200) Subject: alloc-util: add free_many() helper X-Git-Tag: v255-rc1~653 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=24ae45cb65dedb34297188e056874cc944a4d1c8;p=thirdparty%2Fsystemd.git alloc-util: add free_many() helper We often free an array of things. Let's create a common helper for this, and port some potential users over. (Not all, too lazy for that for now). --- diff --git a/src/basic/alloc-util.h b/src/basic/alloc-util.h index 9abe8620c86..e909d5de101 100644 --- a/src/basic/alloc-util.h +++ b/src/basic/alloc-util.h @@ -242,4 +242,17 @@ static inline size_t malloc_sizeof_safe(void **xp) { (char*) memdupa_suffix0(_t, strnlen(_t, (n))); \ }) +/* Free every element of the array. */ +static inline void free_many(void **p, size_t n) { + assert(p || n == 0); + + FOREACH_ARRAY(i, p, n) + *i = mfree(*i); +} + +/* Typesafe wrapper for char** rather than void**. Unfortunately C won't implicitly cast this. */ +static inline void free_many_charp(char **c, size_t n) { + free_many((void**) c, n); +} + #include "memory-util.h" diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c index 21e2255daed..b2b0ddd1907 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -1915,9 +1915,7 @@ int cg_get_keyed_attribute_full( r = -ENXIO; fail: - for (i = 0; i < n; i++) - free(v[i]); - + free_many_charp(v, n); return r; done: diff --git a/src/basic/extract-word.c b/src/basic/extract-word.c index 9f9bb0c7910..160f771b228 100644 --- a/src/basic/extract-word.c +++ b/src/basic/extract-word.c @@ -272,11 +272,7 @@ int extract_many_words(const char **p, const char *separators, unsigned flags, . r = extract_first_word(p, &l[c], separators, flags); if (r < 0) { - int j; - - for (j = 0; j < c; j++) - free(l[j]); - + free_many_charp(l, c); return r; } diff --git a/src/basic/locale-util.c b/src/basic/locale-util.c index d94fbcff4b9..d43f91fd226 100644 --- a/src/basic/locale-util.c +++ b/src/basic/locale-util.c @@ -340,11 +340,7 @@ out: } void locale_variables_free(char *l[_VARIABLE_LC_MAX]) { - if (!l) - return; - - for (LocaleVariable i = 0; i < _VARIABLE_LC_MAX; i++) - l[i] = mfree(l[i]); + free_many_charp(l, _VARIABLE_LC_MAX); } void locale_variables_simplify(char *l[_VARIABLE_LC_MAX]) { diff --git a/src/basic/rlimit-util.c b/src/basic/rlimit-util.c index 91424cd3cce..1cf64d9cdd3 100644 --- a/src/basic/rlimit-util.c +++ b/src/basic/rlimit-util.c @@ -359,13 +359,7 @@ int rlimit_from_string_harder(const char *s) { } void rlimit_free_all(struct rlimit **rl) { - int i; - - if (!rl) - return; - - for (i = 0; i < _RLIMIT_MAX; i++) - rl[i] = mfree(rl[i]); + free_many((void**) rl, _RLIMIT_MAX); } int rlimit_nofile_bump(int limit) { diff --git a/src/basic/strv.c b/src/basic/strv.c index deadb9909e9..37c8f553eb3 100644 --- a/src/basic/strv.c +++ b/src/basic/strv.c @@ -212,9 +212,7 @@ int strv_extend_strv(char ***a, char * const *b, bool filter_duplicates) { return (int) i; rollback: - for (size_t j = 0; j < i; j++) - free(t[p + j]); - + free_many_charp(t + p, i); t[p] = NULL; return -ENOMEM; } diff --git a/src/core/socket.c b/src/core/socket.c index 8b40f6b9763..88e45c7385f 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -1350,9 +1350,7 @@ fail: p->n_auxiliary_fds = 0; clear: - for (size_t i = 0; i < n; ++i) - free(ent[i]); - + free_many((void**) ent, n); return r; } diff --git a/src/core/unit.c b/src/core/unit.c index b1f8d6c5f4d..f1b27d30d3a 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -2546,8 +2546,7 @@ static int unit_log_resources(Unit *u) { r = 0; finish: - for (size_t i = 0; i < n_message_parts; i++) - free(message_parts[i]); + free_many_charp(message_parts, n_message_parts); for (size_t i = 0; i < n_iovec; i++) free(iovec[i].iov_base); diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index 791314e9cc7..d09908b5a2e 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -1159,8 +1159,7 @@ static char **private_options_free(char **options) { if (!options) return NULL; - for (unsigned i = 0; i < SD_DHCP_OPTION_PRIVATE_LAST - SD_DHCP_OPTION_PRIVATE_BASE + 1; i++) - free(options[i]); + free_many_charp(options, SD_DHCP_OPTION_PRIVATE_LAST - SD_DHCP_OPTION_PRIVATE_BASE + 1); return mfree(options); }