From ee175a2a68b97638bf1d7bf73c3e4d64fa6361df Mon Sep 17 00:00:00 2001 From: Juan RP Date: Sat, 10 Jan 2015 19:11:31 +0100 Subject: [PATCH] Improve xbps_end() and use it before exit(3)ing. - Simplify xbps_repo_open::repo_get_dict(). - Use xbps_end() in the utils where necessary. - Make xbps_end() call xbps_pkgdb_unlock() if necessary. - Make xbps_end() release rpool resources. - Make xbps_end() release resources from xbps_handle. - Fixed 90% of reported leaks (still reachable at exit) from valgrind. That was to silence valgrind's memcheck with --leak-check=full. --- bin/xbps-install/main.c | 8 +++----- bin/xbps-pkgdb/main.c | 8 ++++---- bin/xbps-query/main.c | 1 + bin/xbps-query/search.c | 7 +++++-- bin/xbps-query/show-deps.c | 3 ++- bin/xbps-reconfigure/main.c | 4 ++-- include/xbps.h.in | 2 ++ lib/initend.c | 1 + lib/pkgdb.c | 19 ++++++++++++++----- lib/repo.c | 36 +----------------------------------- lib/rpool.c | 16 +++++++++++++++- 11 files changed, 50 insertions(+), 55 deletions(-) diff --git a/bin/xbps-install/main.c b/bin/xbps-install/main.c index 7704f09f..f543241a 100644 --- a/bin/xbps-install/main.c +++ b/bin/xbps-install/main.c @@ -237,7 +237,7 @@ main(int argc, char **argv) for (i = optind; i < argc; i++) { rv = update_pkg(&xh, argv[i]); if (rv != 0) { - xbps_pkgdb_unlock(&xh); + xbps_end(&xh); exit(rv); } } @@ -250,15 +250,13 @@ main(int argc, char **argv) if (npkgs >= 2 && rv == EEXIST) { rv = 0; } else if (rv != 0) { - xbps_pkgdb_unlock(&xh); + xbps_end(&xh); exit(rv); } } rv = exec_transaction(&xh, maxcols, yes, drun); } - if (!drun) - xbps_pkgdb_unlock(&xh); - + xbps_end(&xh); exit(rv); } diff --git a/bin/xbps-pkgdb/main.c b/bin/xbps-pkgdb/main.c index f21d7b1e..99ee783c 100644 --- a/bin/xbps-pkgdb/main.c +++ b/bin/xbps-pkgdb/main.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2013-2014 Juan Romero Pardines. + * Copyright (c) 2013-2015 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -158,7 +158,7 @@ main(int argc, char **argv) if (argc == optind) { fprintf(stderr, "xbps-pkgdb: missing PKGNAME argument\n"); - xbps_pkgdb_unlock(&xh); + xbps_end(&xh); exit(EXIT_FAILURE); } for (i = optind; i < argc; i++) { @@ -167,7 +167,7 @@ main(int argc, char **argv) fprintf(stderr, "xbps-pkgdb: failed to " "change to %s mode to %s: %s\n", instmode, argv[i], strerror(rv)); - xbps_pkgdb_unlock(&xh); + xbps_end(&xh); exit(EXIT_FAILURE); } } @@ -183,6 +183,6 @@ main(int argc, char **argv) } out: - xbps_pkgdb_unlock(&xh); + xbps_end(&xh); exit(rv ? EXIT_FAILURE : EXIT_SUCCESS); } diff --git a/bin/xbps-query/main.c b/bin/xbps-query/main.c index e976504c..803b0521 100644 --- a/bin/xbps-query/main.c +++ b/bin/xbps-query/main.c @@ -296,5 +296,6 @@ main(int argc, char **argv) rv = show_pkg_revdeps(&xh, pkg, repo_mode); } + xbps_end(&xh); exit(rv); } diff --git a/bin/xbps-query/search.c b/bin/xbps-query/search.c index c0da3fca..2027e937 100644 --- a/bin/xbps-query/search.c +++ b/bin/xbps-query/search.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2008-2014 Juan Romero Pardines. + * Copyright (c) 2008-2015 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -230,13 +230,16 @@ search_repo_cb(struct xbps_repo *repo, void *arg, bool *done _unused) { xbps_array_t allkeys; struct search_data *sd = arg; + int rv; if (repo->idx == NULL) return 0; sd->repourl = repo->uri; allkeys = xbps_dictionary_all_keys(repo->idx); - return xbps_array_foreach_cb(repo->xhp, allkeys, repo->idx, search_array_cb, sd); + rv = xbps_array_foreach_cb(repo->xhp, allkeys, repo->idx, search_array_cb, sd); + xbps_object_release(allkeys); + return rv; } int diff --git a/bin/xbps-query/show-deps.c b/bin/xbps-query/show-deps.c index feebc471..c453644f 100644 --- a/bin/xbps-query/show-deps.c +++ b/bin/xbps-query/show-deps.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009-2014 Juan Romero Pardines. + * Copyright (c) 2009-2015 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -85,5 +85,6 @@ show_pkg_revdeps(struct xbps_handle *xhp, const char *pkg, bool repomode) xbps_array_get_cstring_nocopy(revdeps, i, &pkgdep); printf("%s\n", pkgdep); } + xbps_object_release(revdeps); return 0; } diff --git a/bin/xbps-reconfigure/main.c b/bin/xbps-reconfigure/main.c index 724ef18c..8b14c2a0 100644 --- a/bin/xbps-reconfigure/main.c +++ b/bin/xbps-reconfigure/main.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2012-2014 Juan Romero Pardines. + * Copyright (c) 2012-2015 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -182,6 +182,6 @@ main(int argc, char **argv) } } } - xbps_pkgdb_unlock(&xh); + xbps_end(&xh); exit(rv ? EXIT_FAILURE : EXIT_SUCCESS); } diff --git a/include/xbps.h.in b/include/xbps.h.in index c2333462..cd4ce4b8 100644 --- a/include/xbps.h.in +++ b/include/xbps.h.in @@ -1269,6 +1269,8 @@ struct xbps_repo { bool is_signed; }; +void xbps_rpool_release(struct xbps_handle *xhp); + /** * Synchronizes repository data for all remote repositories * as specified in the configuration file or if \a uri argument is diff --git a/lib/initend.c b/lib/initend.c index 8465a063..bb37e00d 100644 --- a/lib/initend.c +++ b/lib/initend.c @@ -502,6 +502,7 @@ xbps_end(struct xbps_handle *xhp) assert(xhp); xbps_pkgdb_release(xhp); + xbps_rpool_release(xhp); xbps_fetch_unset_cache_connection(); } diff --git a/lib/pkgdb.c b/lib/pkgdb.c index d3f6f708..7179dd11 100644 --- a/lib/pkgdb.c +++ b/lib/pkgdb.c @@ -109,11 +109,13 @@ xbps_pkgdb_unlock(struct xbps_handle *xhp) { (void)xbps_pkgdb_update(xhp, true); - if (lockf(pkgdb_fd, F_ULOCK, 0) == -1) - xbps_dbg_printf(xhp, "[pkgdb] failed to unlock pkgdb: %s\n", strerror(errno)); + if (pkgdb_fd != -1) { + if (lockf(pkgdb_fd, F_ULOCK, 0) == -1) + xbps_dbg_printf(xhp, "[pkgdb] failed to unlock pkgdb: %s\n", strerror(errno)); - (void)close(pkgdb_fd); - pkgdb_fd = -1; + (void)close(pkgdb_fd); + pkgdb_fd = -1; + } } static int @@ -247,8 +249,15 @@ xbps_pkgdb_release(struct xbps_handle *xhp) if (xhp->pkgdb == NULL) return; + if (xhp->pkgdb_revdeps) + xbps_object_release(xhp->pkgdb_revdeps); + if (xhp->vpkgd) + xbps_object_release(xhp->vpkgd); + if (xhp->preserved_files) + xbps_object_release(xhp->preserved_files); + + xbps_pkgdb_unlock(xhp); xbps_object_release(xhp->pkgdb); - xhp->pkgdb = NULL; xbps_dbg_printf(xhp, "[pkgdb] released ok.\n"); } diff --git a/lib/repo.c b/lib/repo.c index c458e13f..ca4be72c 100644 --- a/lib/repo.c +++ b/lib/repo.c @@ -57,12 +57,7 @@ xbps_repo_path(struct xbps_handle *xhp, const char *url) static xbps_dictionary_t repo_get_dict(struct xbps_repo *repo) { - xbps_dictionary_t d = NULL; struct archive_entry *entry; - char *adata = NULL; - const void *buf; - off_t offset; - size_t size; int rv; if (repo->ar == NULL) @@ -75,35 +70,7 @@ repo_get_dict(struct xbps_repo *repo) archive_error_string(repo->ar)); return NULL; } - for (;;) { - rv = archive_read_data_block(repo->ar, &buf, &size, &offset); - if (rv == ARCHIVE_EOF) - break; - if (rv != ARCHIVE_OK) { - if (adata != NULL) - free(adata); - - xbps_dbg_printf(repo->xhp, - "%s: read_data_block %s\n", repo->uri, - archive_error_string(repo->ar)); - return NULL; - } - if (adata == NULL) { - adata = malloc(size); - } else { - adata = realloc(adata, size+offset); - if (adata == NULL) { - free(adata); - return NULL; - } - } - memcpy(adata+offset, buf, size); - } - if (adata != NULL) { - d = xbps_dictionary_internalize(adata); - free(adata); - } - return d; + return xbps_archive_get_dictionary(repo->ar, entry); } static bool @@ -304,7 +271,6 @@ xbps_repo_close(struct xbps_repo *repo, bool lock) xbps_dbg_printf(repo->xhp, "[repo] failed to unlock %s: %s\n", repo->uri, strerror(errno)); close(repo->fd); - free(repo); } xbps_dictionary_t diff --git a/lib/rpool.c b/lib/rpool.c index e73ac2f2..a8a61a95 100644 --- a/lib/rpool.c +++ b/lib/rpool.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009-2014 Juan Romero Pardines. + * Copyright (c) 2009-2015 Juan Romero Pardines. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -91,6 +91,20 @@ xbps_rpool_get_repo(const char *url) return NULL; } +void +xbps_rpool_release(struct xbps_handle *xhp _unused) +{ + struct xbps_repo *repo; + + while ((repo = SIMPLEQ_FIRST(&rpool_queue))) { + SIMPLEQ_REMOVE(&rpool_queue, repo, xbps_repo, entries); + xbps_repo_close(repo, true); + free(repo); + } + if (xhp->repositories) + xbps_object_release(xhp->repositories); +} + int xbps_rpool_foreach(struct xbps_handle *xhp, int (*fn)(struct xbps_repo *, void *, bool *),