systemctl: use _cleanup_ for UnitFileList hash
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)
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user