From: ticktock35 Date: Mon, 15 Dec 2008 05:18:11 +0000 (+0000) Subject: opkg: (leak fixing, day 1) lots and lots of memory leaks fixed X-Git-Url: https://git.librecmc.org/?p=oweals%2Fopkg-lede.git;a=commitdiff_plain;h=90299e3df5c5d5eb4ae2189b11e44ec83995ca62 opkg: (leak fixing, day 1) lots and lots of memory leaks fixed git-svn-id: http://opkg.googlecode.com/svn/trunk@114 e8e0d7a0-c8d9-11dd-a880-a1081c7ac358 --- diff --git a/libopkg/hash_table.c b/libopkg/hash_table.c index 41877c2..c0c0530 100644 --- a/libopkg/hash_table.c +++ b/libopkg/hash_table.c @@ -78,7 +78,26 @@ int hash_table_init(const char *name, hash_table_t *hash, int len) void hash_table_deinit(hash_table_t *hash) { - free(hash->entries); + int i; + if (!hash) + return; + + /* free the reminaing entries */ + for (i = 0; i < hash->n_entries; i++) { + hash_entry_t *hash_entry = (hash->entries + i); + /* skip the first entry as this is part of the array */ + hash_entry = hash_entry->next; + while (hash_entry) + { + hash_entry_t *old = hash_entry; + hash_entry = hash_entry->next; + free (old->key); + free (old); + } + } + + free (hash->entries); + hash->entries = NULL; hash->n_entries = 0; } diff --git a/libopkg/hash_table.h b/libopkg/hash_table.h index 388a966..d4e8a3d 100644 --- a/libopkg/hash_table.h +++ b/libopkg/hash_table.h @@ -22,7 +22,7 @@ typedef struct hash_entry hash_entry_t; typedef struct hash_table hash_table_t; struct hash_entry { - const char * key; + char * key; void * data; struct hash_entry * next; }; diff --git a/libopkg/opkg_conf.c b/libopkg/opkg_conf.c index e2cbae5..2642033 100644 --- a/libopkg/opkg_conf.c +++ b/libopkg/opkg_conf.c @@ -179,7 +179,7 @@ int opkg_conf_init(opkg_conf_t *conf, const args_t *args) } if (args->offline_root) { - char *tmp = malloc(strlen(lists_dir) + strlen(args->offline_root) + 1); + char *tmp;// = malloc(strlen(lists_dir) + strlen(args->offline_root) + 1); sprintf_alloc(&tmp, "%s/%s",args->offline_root,lists_dir); free(lists_dir); lists_dir = tmp; @@ -195,6 +195,8 @@ int opkg_conf_init(opkg_conf_t *conf, const args_t *args) sprintf_alloc(&etc_opkg_conf_pattern, "%s/etc/opkg/*.conf", args->offline_root); memset(&globbuf, 0, sizeof(globbuf)); err = glob(etc_opkg_conf_pattern, 0, NULL, &globbuf); + if (args->offline_root) + free (etc_opkg_conf_pattern); if (!err) { int i; for (i = 0; i < globbuf.gl_pathc; i++) { @@ -327,6 +329,7 @@ void opkg_conf_deinit(opkg_conf_t *conf) #endif /* OPKG_DEBUG_NO_TMP_CLEANUP */ free(conf->tmp_dir); /*XXX*/ + free(conf->lists_dir); pkg_src_list_deinit(&conf->pkg_src_list); pkg_dest_list_deinit(&conf->pkg_dest_list); diff --git a/libopkg/opkg_conf.h b/libopkg/opkg_conf.h index bc8d36f..fe29e00 100644 --- a/libopkg/opkg_conf.h +++ b/libopkg/opkg_conf.h @@ -49,7 +49,7 @@ struct opkg_conf pkg_dest_t *default_dest; char *tmp_dir; - const char *lists_dir; + char *lists_dir; const char *pending_dir; /* options */ diff --git a/libopkg/pkg.c b/libopkg/pkg.c index 3038b4b..d9bae89 100644 --- a/libopkg/pkg.c +++ b/libopkg/pkg.c @@ -144,6 +144,8 @@ int pkg_init(pkg_t *pkg) void pkg_deinit(pkg_t *pkg) { + int i; + free(pkg->name); pkg->name = NULL; pkg->epoch = 0; @@ -168,18 +170,65 @@ void pkg_deinit(pkg_t *pkg) pkg->state_want = SW_UNKNOWN; pkg->state_flag = SF_OK; pkg->state_status = SS_NOT_INSTALLED; + + for (i = 0; i < pkg->depends_count; i++) + free (pkg->depends_str[i]); free(pkg->depends_str); pkg->depends_str = NULL; + pkg->depends_count = 0; + + for (i = 0; i < pkg->provides_count; i++) + free (pkg->provides_str[i]); free(pkg->provides_str); pkg->provides_str = NULL; - pkg->depends_count = 0; - /* XXX: CLEANUP: MEMORY_LEAK: how to free up pkg->depends ? */ + pkg->provides_count = 0; + + for (i = 0; i < pkg->conflicts_count; i++) + free (pkg->conflicts_str[i]); + free(pkg->conflicts_str); + pkg->conflicts_str = NULL; + pkg->conflicts_count = 0; + + for (i = 0; i < pkg->replaces_count; i++) + free (pkg->replaces_str[i]); + free(pkg->replaces_str); + pkg->replaces_str = NULL; + pkg->replaces_count = 0; + + for (i = 0; i < pkg->recommends_count; i++) + free (pkg->recommends_str[i]); + free(pkg->recommends_str); + pkg->recommends_str = NULL; + pkg->recommends_count = 0; + + if (pkg->depends) + { + int count = pkg->pre_depends_count + pkg->depends_count + pkg->recommends_count + pkg->suggests_count; + int x; + + for (x = 0; x < count; x++) + { + compound_depend_t *depends; + depends = &pkg->depends[x]; + + for (i = 0; i < depends->possibility_count; i++) + { + depend_t *d; + d = depends->possibilities[i]; + free (d->version); + free (d); + } + free (depends->possibilities); + } + free (pkg->depends); + } + free (pkg->provides); + free (pkg->conflicts); + pkg->pre_depends_count = 0; free(pkg->pre_depends_str); pkg->pre_depends_str = NULL; pkg->provides_count = 0; - /* XXX: CLEANUP: MEMORY_LEAK: how to free up pkg->provides ? */ - /* XXX: CLEANUP: MEMORY_LEAK: how to free up pkg->suggests ? */ free(pkg->filename); pkg->filename = NULL; free(pkg->local_filename); diff --git a/libopkg/pkg_hash.c b/libopkg/pkg_hash.c index b293195..580fe6e 100644 --- a/libopkg/pkg_hash.c +++ b/libopkg/pkg_hash.c @@ -53,8 +53,34 @@ int pkg_hash_init(const char *name, hash_table_t *hash, int len) return hash_table_init(name, hash, len); } +void free_pkgs (const char *key, void *entry, void *data) +{ + int i; + abstract_pkg_t *ab_pkg; + + /* each entry in the hash table is an abstract package, which contains a list + * of packages that provide the abstract package */ + + ab_pkg = (abstract_pkg_t*) entry; + + if (ab_pkg->pkgs) + { + for (i = 0; i < ab_pkg->pkgs->len; i++) + { + pkg_deinit (ab_pkg->pkgs->pkgs[i]); + free (ab_pkg->pkgs->pkgs[i]); + } + } + + abstract_pkg_vec_free (ab_pkg->provided_by); + pkg_vec_free (ab_pkg->pkgs); + free (ab_pkg->name); + free (ab_pkg); +} + void pkg_hash_deinit(hash_table_t *hash) { + hash_table_foreach (hash, free_pkgs, NULL); hash_table_deinit(hash); } diff --git a/libopkg/pkg_vec.c b/libopkg/pkg_vec.c index 436622a..72f9d7d 100644 --- a/libopkg/pkg_vec.c +++ b/libopkg/pkg_vec.c @@ -36,7 +36,12 @@ pkg_vec_t * pkg_vec_alloc(void) void pkg_vec_free(pkg_vec_t *vec) { - free(vec->pkgs); + if (!vec) + return; + + if (vec->pkgs) + free(vec->pkgs); + free(vec); }