[pacman-dev] [PATCH] pacman+libalpm: handle search errors

Allan McRae allan at archlinux.org
Fri Nov 8 12:08:48 UTC 2019


On 6/11/19 11:42 am, morganamilo wrote:
> 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 <morganamilo at gmail.com>
>

Looks good to me.   Only one bit I need to have a decent thing about,
but I think that it is fine.

Unless anyone else has a comment, I'll accept as is.

Allan

> 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);

OK

>
>  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);
>  }
>

OK

>  /** 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;

I had to think about this.   Is trying to search a db that is labeled as
not being valid to search an error?  That would require callers to check
database usage before searching. /This way, libalpm does the filtering.
I'm going to say this is fine...

>  	}
>
>  	/* 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(&reg, 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) {

OK

> @@ -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(&reg);
>  	}
>
> -	return ret;
> +	return 0;
>  }
>

OK

>  /* 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);

OK.

> 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);

OK

> 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;
> +

OK

>  }
>
>  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;

OK

>  	}
>
>  	return (found == 0);
>


More information about the pacman-dev mailing list