From: Zbigniew Jędrzejewski-Szmek Date: Wed, 8 Apr 2026 16:27:34 +0000 (+0200) Subject: Add DEFINE_ARRAY_FREE_FUNC and mount_image_free_array X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=81d2d0270bb38d5a4087ef4eebb771b37b70b75e;p=thirdparty%2Fsystemd.git Add DEFINE_ARRAY_FREE_FUNC and mount_image_free_array This is similar to DEFINE_POINTER_ARRAY_FREE_FUNC, but one pointer chase less. The name of the outer and inner functions are specified separately. The inner function does not free, so it'll be generally something like 'foo_done', but the outer function does free, so it can be called 'foo_array_free'. --- diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index 9e6077c7e1f..9843836eaf0 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -4055,7 +4055,7 @@ int bus_exec_context_set_transient_property( MountImage *mount_images = NULL; size_t n_mount_images = 0; - CLEANUP_ARRAY(mount_images, n_mount_images, mount_image_free_many); + CLEANUP_ARRAY(mount_images, n_mount_images, mount_image_free_array); r = sd_bus_message_enter_container(message, 'a', "(ssba(ss))"); if (r < 0) @@ -4127,7 +4127,7 @@ int bus_exec_context_set_transient_property( if (!UNIT_WRITE_FLAGS_NOOP(flags)) { if (n_mount_images == 0) { - mount_image_free_many(c->mount_images, c->n_mount_images); + mount_image_free_array(c->mount_images, c->n_mount_images); c->mount_images = NULL; c->n_mount_images = 0; @@ -4158,7 +4158,7 @@ int bus_exec_context_set_transient_property( MountImage *extension_images = NULL; size_t n_extension_images = 0; - CLEANUP_ARRAY(extension_images, n_extension_images, mount_image_free_many); + CLEANUP_ARRAY(extension_images, n_extension_images, mount_image_free_array); r = sd_bus_message_enter_container(message, 'a', "(sba(ss))"); if (r < 0) @@ -4220,7 +4220,7 @@ int bus_exec_context_set_transient_property( if (!UNIT_WRITE_FLAGS_NOOP(flags)) { if (n_extension_images == 0) { - mount_image_free_many(c->extension_images, c->n_extension_images); + mount_image_free_array(c->extension_images, c->n_extension_images); c->extension_images = NULL; c->n_extension_images = 0; diff --git a/src/core/execute.c b/src/core/execute.c index 3661b8c98f6..e6cb9e5cc86 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -696,10 +696,10 @@ void exec_context_done(ExecContext *c) { bind_mount_free_many(c->bind_mounts, c->n_bind_mounts); c->bind_mounts = NULL; c->n_bind_mounts = 0; - mount_image_free_many(c->mount_images, c->n_mount_images); + mount_image_free_array(c->mount_images, c->n_mount_images); c->mount_images = NULL; c->n_mount_images = 0; - mount_image_free_many(c->extension_images, c->n_extension_images); + mount_image_free_array(c->extension_images, c->n_extension_images); c->extension_images = NULL; c->n_extension_images = 0; c->extension_directories = strv_free(c->extension_directories); diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 840804fcf8d..98e63b6cc8d 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -5235,7 +5235,7 @@ int config_parse_mount_images( if (isempty(rvalue)) { /* Empty assignment resets the list */ - mount_image_free_many(c->mount_images, c->n_mount_images); + mount_image_free_array(c->mount_images, c->n_mount_images); c->mount_images = NULL; c->n_mount_images = 0; return 0; @@ -5385,7 +5385,7 @@ int config_parse_extension_images( if (isempty(rvalue)) { /* Empty assignment resets the list */ - mount_image_free_many(c->extension_images, c->n_extension_images); + mount_image_free_array(c->extension_images, c->n_extension_images); c->extension_images = NULL; c->n_extension_images = 0; return 0; diff --git a/src/core/namespace.c b/src/core/namespace.c index 6e4ec80dc96..ff4592b8b90 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -3250,18 +3250,15 @@ int bind_mount_add(BindMount **b, size_t *n, const BindMount *item) { return 0; } -void mount_image_free_many(MountImage *m, size_t n) { - assert(m || n == 0); - - FOREACH_ARRAY(i, m, n) { - free(i->source); - free(i->destination); - mount_options_free_all(i->mount_options); - } - - free(m); +static void mount_image_done(MountImage *m) { + assert(m); + m->source = mfree(m->source); + m->destination = mfree(m->destination); + m->mount_options = mount_options_free_all(m->mount_options); } +DEFINE_ARRAY_FREE_FUNC(mount_image_free_array, MountImage, mount_image_done); + int mount_image_add(MountImage **m, size_t *n, const MountImage *item) { _cleanup_free_ char *s = NULL, *d = NULL; _cleanup_(mount_options_free_allp) MountOptions *o = NULL; diff --git a/src/core/namespace.h b/src/core/namespace.h index f5d792dd771..d25859f17aa 100644 --- a/src/core/namespace.h +++ b/src/core/namespace.h @@ -303,7 +303,7 @@ DECLARE_STRING_TABLE_LOOKUP(private_pids, PrivatePIDs); void bind_mount_free_many(BindMount *b, size_t n); int bind_mount_add(BindMount **b, size_t *n, const BindMount *item); -void mount_image_free_many(MountImage *m, size_t n); +void mount_image_free_array(MountImage *array, size_t n); int mount_image_add(MountImage **m, size_t *n, const MountImage *item); void temporary_filesystem_free_many(TemporaryFileSystem *t, size_t n); diff --git a/src/fundamental/cleanup-fundamental.h b/src/fundamental/cleanup-fundamental.h index b4f23a59204..9094cff2331 100644 --- a/src/fundamental/cleanup-fundamental.h +++ b/src/fundamental/cleanup-fundamental.h @@ -64,6 +64,16 @@ free(array); \ } +/* Clean up an array of objects of known size by dropping all the items in it. + * Then free the array itself. */ +#define DEFINE_ARRAY_FREE_FUNC(name, type, helper) \ + void name(type *array, size_t n) { \ + assert(array || n == 0); \ + FOREACH_ARRAY(item, array, n) \ + helper(item); \ + free(array); \ + } + typedef void (*free_array_func_t)(void *p, size_t n); /* An automatic _cleanup_-like logic for destroy arrays (i.e. pointers + size) when leaving scope */