]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
alloc-util: add free_many() helper
authorLennart Poettering <lennart@poettering.net>
Wed, 23 Aug 2023 12:29:40 +0000 (14:29 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 24 Aug 2023 13:04:33 +0000 (15:04 +0200)
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).

src/basic/alloc-util.h
src/basic/cgroup-util.c
src/basic/extract-word.c
src/basic/locale-util.c
src/basic/rlimit-util.c
src/basic/strv.c
src/core/socket.c
src/core/unit.c
src/libsystemd-network/sd-dhcp-lease.c

index 9abe8620c86066bb9d82ae73e8bfa0e2040cc98d..e909d5de101d58d21ac7586311a3c5bd3931e806 100644 (file)
@@ -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"
index 21e2255daed511a040a5189cb493e699332fef19..b2b0ddd1907b3272f4772a7db41e7c4e2a53114e 100644 (file)
@@ -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:
index 9f9bb0c7910cd44629cdf239ea7106ce1b29f2ee..160f771b228f631ca40847470156bc445b35a1c1 100644 (file)
@@ -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;
                 }
 
index d94fbcff4b97d2fef939dcf666970272d886834e..d43f91fd226b96bc633dd6f5fb453cd27156a60b 100644 (file)
@@ -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]) {
index 91424cd3cced0e121c7d20db22d7cd573839b3ea..1cf64d9cdd3126d192c976a67f77cf01eb962804 100644 (file)
@@ -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) {
index deadb9909e99b7643a0934043200b7c48cbe596e..37c8f553eb3f53cbc56eb840936f7505816eed59 100644 (file)
@@ -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;
 }
index 8b40f6b97637d7538dbe37441ca2144eeb88fbac..88e45c7385fc9eac4fe45b608b75030282f23b30 100644 (file)
@@ -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;
 }
 
index b1f8d6c5f4d65ab2ebbf2a6a2ac6ac629b74ee2e..f1b27d30d3a1da0ec515b8149b1e089107218cb7 100644 (file)
@@ -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);
index 791314e9cc7fbb4eff9525703b62d1da11fb45e2..d09908b5a2e6a3edab68d812558ee1ae3b5feacd 100644 (file)
@@ -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);
 }