]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
systemctl: use _cleanup_ for UnitFileList hash
authorDavid Tardon <dtardon@redhat.com>
Tue, 28 Mar 2023 07:36:14 +0000 (09:36 +0200)
committerDavid Tardon <dtardon@redhat.com>
Wed, 12 Apr 2023 15:03:55 +0000 (17:03 +0200)
This also fixes a memory leak in the old code.

valgrind systemctl -t socket --root=/ list-unit-files >/dev/null
==2601899== Memcheck, a memory error detector
==2601899== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==2601899== Using Valgrind-3.20.0 and LibVEX; rerun with -h for copyright info
==2601899== Command: systemctl -t socket --root=/ list-unit-files
==2601899==
==2601899==
==2601899== HEAP SUMMARY:
==2601899==     in use at exit: 39,984 bytes in 994 blocks
==2601899==   total heap usage: 344,414 allocs, 343,420 frees, 2,001,612,404 bytes allocated
==2601899==
==2601899== LEAK SUMMARY:
==2601899==    definitely lost: 7,952 bytes in 497 blocks
==2601899==    indirectly lost: 32,032 bytes in 497 blocks
==2601899==      possibly lost: 0 bytes in 0 blocks
==2601899==    still reachable: 0 bytes in 0 blocks
==2601899==         suppressed: 0 bytes in 0 blocks
==2601899== Rerun with --leak-check=full to see details of leaked memory
==2601899==
==2601899== For lists of detected and suppressed errors, rerun with: -s
==2601899== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

src/systemctl/systemctl-list-unit-files.c

index 72b377cde6152a5c9580d19ab521037cb882e889..426ba1acc76df64c367b58cd0071df90eac85112 100644 (file)
@@ -136,6 +136,7 @@ static int output_unit_file_list(const UnitFileList *units, unsigned c) {
 int verb_list_unit_files(int argc, char *argv[], void *userdata) {
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
         _cleanup_free_ UnitFileList *units = NULL;
+        _cleanup_(hashmap_freep) Hashmap *h = NULL;
         unsigned c = 0;
         const char *state;
         char *path;
@@ -143,38 +144,31 @@ int verb_list_unit_files(int argc, char *argv[], void *userdata) {
         bool fallback = false;
 
         if (install_client_side()) {
-                Hashmap *h;
                 UnitFileList *u;
                 unsigned n_units;
 
-                h = hashmap_new(&string_hash_ops);
+                h = hashmap_new(&unit_file_list_hash_ops_free);
                 if (!h)
                         return log_oom();
 
                 r = unit_file_get_list(arg_runtime_scope, arg_root, h, arg_states, strv_skip(argv, 1));
-                if (r < 0) {
-                        unit_file_list_free(h);
+                if (r < 0)
                         return log_error_errno(r, "Failed to get unit file list: %m");
-                }
 
                 n_units = hashmap_size(h);
 
                 units = new(UnitFileList, n_units ?: 1); /* avoid malloc(0) */
-                if (!units) {
-                        unit_file_list_free(h);
+                if (!units)
                         return log_oom();
-                }
 
                 HASHMAP_FOREACH(u, h) {
                         if (!output_show_unit_file(u, NULL, NULL))
                                 continue;
 
                         units[c++] = *u;
-                        free(u);
                 }
 
                 assert(c <= n_units);
-                hashmap_free(h);
 
                 r = 0;
         } else {
@@ -262,10 +256,6 @@ int verb_list_unit_files(int argc, char *argv[], void *userdata) {
         if (r < 0)
                 return r;
 
-        if (install_client_side())
-                for (UnitFileList *unit = units; unit < units + c; unit++)
-                        free(unit->path);
-
         if (c == 0)
                 return -ENOENT;