From 27f354a7874b965bf223832bdf9749504cd1a590 Mon Sep 17 00:00:00 2001 From: morganamilo Date: Wed, 6 Nov 2019 01:42:11 +0000 Subject: pacman+libalpm: handle search errors Previously, pacman treated no matches and an error during search the same. To fix this, alpm_db_search now returns its status as an int and instead takes the to be returned list as a param. Allowing front ends to easily differentiate between errors and no matches. Signed-off-by: morganamilo Signed-off-by: Allan McRae --- lib/libalpm/alpm.h | 6 ++++-- lib/libalpm/db.c | 24 +++++++++++++----------- lib/libalpm/db.h | 3 ++- src/pacman/package.c | 7 +++++-- src/pacman/query.c | 10 +++++++++- src/pacman/sync.c | 10 +++++++++- 6 files changed, 42 insertions(+), 18 deletions(-) diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 4486da44..d3630385 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -997,9 +997,11 @@ alpm_list_t *alpm_db_get_groupcache(alpm_db_t *db); /** Searches a database with regular expressions. * @param db pointer to the package database to search in * @param needles a list of regular expressions to search for - * @return the list of packages matching all regular expressions on success, NULL on error + * @param ret the list of packages matching all regular expressions + * @return 0 on success, -1 on error (pm_errno is set accordingly) */ -alpm_list_t *alpm_db_search(alpm_db_t *db, const alpm_list_t *needles); +int alpm_db_search(alpm_db_t *db, const alpm_list_t *needles, + alpm_list_t **ret); typedef enum _alpm_db_usage_t { ALPM_DB_USAGE_SYNC = 1, diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c index a443e552..cf4c865f 100644 --- a/lib/libalpm/db.c +++ b/lib/libalpm/db.c @@ -298,12 +298,14 @@ alpm_list_t SYMEXPORT *alpm_db_get_groupcache(alpm_db_t *db) } /** Searches a database. */ -alpm_list_t SYMEXPORT *alpm_db_search(alpm_db_t *db, const alpm_list_t *needles) +int SYMEXPORT alpm_db_search(alpm_db_t *db, const alpm_list_t *needles, + alpm_list_t **ret) { - ASSERT(db != NULL, return NULL); + ASSERT(db != NULL && ret != NULL && *ret == NULL, + RET_ERR(db->handle, ALPM_ERR_WRONG_ARGS, -1)); db->handle->pm_errno = ALPM_ERR_OK; - return _alpm_db_search(db, needles); + return _alpm_db_search(db, needles, ret); } /** Sets the usage bitmask for a repo */ @@ -396,13 +398,13 @@ int _alpm_db_cmp(const void *d1, const void *d2) return strcmp(db1->treename, db2->treename); } -alpm_list_t *_alpm_db_search(alpm_db_t *db, const alpm_list_t *needles) +int _alpm_db_search(alpm_db_t *db, const alpm_list_t *needles, + alpm_list_t **ret) { const alpm_list_t *i, *j, *k; - alpm_list_t *ret = NULL; if(!(db->usage & ALPM_DB_USAGE_SEARCH)) { - return NULL; + return 0; } /* copy the pkgcache- we will free the list var after each needle */ @@ -415,12 +417,12 @@ alpm_list_t *_alpm_db_search(alpm_db_t *db, const alpm_list_t *needles) if(i->data == NULL) { continue; } - ret = NULL; + *ret = NULL; targ = i->data; _alpm_log(db->handle, ALPM_LOG_DEBUG, "searching for target '%s'\n", targ); if(regcomp(®, targ, REG_EXTENDED | REG_NOSUB | REG_ICASE | REG_NEWLINE) != 0) { - RET_ERR(db->handle, ALPM_ERR_INVALID_REGEX, NULL); + RET_ERR(db->handle, ALPM_ERR_INVALID_REGEX, -1); } for(j = list; j; j = j->next) { @@ -463,18 +465,18 @@ alpm_list_t *_alpm_db_search(alpm_db_t *db, const alpm_list_t *needles) _alpm_log(db->handle, ALPM_LOG_DEBUG, "search target '%s' matched '%s' on package '%s'\n", targ, matched, name); - ret = alpm_list_add(ret, pkg); + *ret = alpm_list_add(*ret, pkg); } } /* Free the existing search list, and use the returned list for the * next needle. This allows for AND-based package searching. */ alpm_list_free(list); - list = ret; + list = *ret; regfree(®); } - return ret; + return 0; } /* Returns a new package cache from db. diff --git a/lib/libalpm/db.h b/lib/libalpm/db.h index f17444e6..e7ad98f5 100644 --- a/lib/libalpm/db.h +++ b/lib/libalpm/db.h @@ -87,7 +87,8 @@ alpm_db_t *_alpm_db_new(const char *treename, int is_local); void _alpm_db_free(alpm_db_t *db); const char *_alpm_db_path(alpm_db_t *db); int _alpm_db_cmp(const void *d1, const void *d2); -alpm_list_t *_alpm_db_search(alpm_db_t *db, const alpm_list_t *needles); +int _alpm_db_search(alpm_db_t *db, const alpm_list_t *needles, + alpm_list_t **ret); alpm_db_t *_alpm_db_register_local(alpm_handle_t *handle); alpm_db_t *_alpm_db_register_sync(alpm_handle_t *handle, const char *treename, int level); diff --git a/src/pacman/package.c b/src/pacman/package.c index 35cfcd94..ec6e78fc 100644 --- a/src/pacman/package.c +++ b/src/pacman/package.c @@ -518,12 +518,13 @@ void print_groups(alpm_pkg_t *pkg) * @param db the database we're searching * @param targets the targets we're searching for * @param show_status show if the package is also in the local db + * @return -1 on error, 0 if there were matches, 1 if there were not */ int dump_pkg_search(alpm_db_t *db, alpm_list_t *targets, int show_status) { int freelist = 0; alpm_db_t *db_local; - alpm_list_t *i, *searchlist; + alpm_list_t *i, *searchlist = NULL; unsigned short cols; const colstr_t *colstr = &config->colstr; @@ -533,7 +534,9 @@ int dump_pkg_search(alpm_db_t *db, alpm_list_t *targets, int show_status) /* if we have a targets list, search for packages matching it */ if(targets) { - searchlist = alpm_db_search(db, targets); + if(alpm_db_search(db, targets, &searchlist) != 0) { + return -1; + } freelist = 1; } else { searchlist = alpm_db_get_pkgcache(db); diff --git a/src/pacman/query.c b/src/pacman/query.c index 2b9ee7a6..bdcfc3c1 100644 --- a/src/pacman/query.c +++ b/src/pacman/query.c @@ -233,7 +233,15 @@ targcleanup: static int query_search(alpm_list_t *targets) { alpm_db_t *db_local = alpm_get_localdb(config->handle); - return dump_pkg_search(db_local, targets, 0); + int ret = dump_pkg_search(db_local, targets, 0); + if(ret == -1) { + alpm_errno_t err = alpm_errno(config->handle); + pm_printf(ALPM_LOG_ERROR, "search failed: %s\n", alpm_strerror(err)); + return 1; + } + + return ret; + } static unsigned short pkg_get_locality(alpm_pkg_t *pkg) diff --git a/src/pacman/sync.c b/src/pacman/sync.c index 9033cee7..4bdeff7b 100644 --- a/src/pacman/sync.c +++ b/src/pacman/sync.c @@ -311,7 +311,15 @@ static int sync_search(alpm_list_t *syncs, alpm_list_t *targets) for(i = syncs; i; i = alpm_list_next(i)) { alpm_db_t *db = i->data; - found += !dump_pkg_search(db, targets, 1); + int ret = dump_pkg_search(db, targets, 1); + + if(ret == -1) { + alpm_errno_t err = alpm_errno(config->handle); + pm_printf(ALPM_LOG_ERROR, "search failed: %s\n", alpm_strerror(err)); + return 1; + } + + found += !ret; } return (found == 0); -- cgit v1.2.3-24-g4f1b