From 652aff97906d7eadca6fe727b16f6511d8dbfe05 Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Sun, 8 Oct 2023 22:27:56 +0000 Subject: [PATCH] path: add pkgconf_path_prepend API for --with-path Otherwise, PKG_CONFIG_PATH and PKG_CONFIG_LIBDIR elements would be processed backwards. Fixes: 384ade5 (path: prepend paths rather than append paths when processing --with-path arguments) Closes: #250 Signed-off-by: Ariadne Conill --- cli/main.c | 2 +- libpkgconf/libpkgconf.h | 1 + libpkgconf/path.c | 102 ++++++++++++++++++++++++++-------------- 3 files changed, 69 insertions(+), 36 deletions(-) diff --git a/cli/main.c b/cli/main.c index c94d1e0..76cd9c2 100644 --- a/cli/main.c +++ b/cli/main.c @@ -967,7 +967,7 @@ main(int argc, char *argv[]) logfile_arg = pkg_optarg; break; case 42: - pkgconf_path_add(pkg_optarg, &dir_list, true); + pkgconf_path_prepend(pkg_optarg, &dir_list, true); break; case 43: pkgconf_client_set_prefix_varname(&pkg_client, pkg_optarg); diff --git a/libpkgconf/libpkgconf.h b/libpkgconf/libpkgconf.h index d6f8f63..ca5d63f 100644 --- a/libpkgconf/libpkgconf.h +++ b/libpkgconf/libpkgconf.h @@ -411,6 +411,7 @@ PKGCONF_API void pkgconf_audit_log_dependency(pkgconf_client_t *client, const pk /* path.c */ PKGCONF_API void pkgconf_path_add(const char *text, pkgconf_list_t *dirlist, bool filter); +PKGCONF_API void pkgconf_path_prepend(const char *text, pkgconf_list_t *dirlist, bool filter); PKGCONF_API size_t pkgconf_path_split(const char *text, pkgconf_list_t *dirlist, bool filter); PKGCONF_API size_t pkgconf_path_build_from_environ(const char *envvarname, const char *fallback, pkgconf_list_t *dirlist, bool filter); PKGCONF_API bool pkgconf_path_match_list(const char *path, const pkgconf_list_t *dirlist); diff --git a/libpkgconf/path.c b/libpkgconf/path.c index a48a226..89054dd 100644 --- a/libpkgconf/path.c +++ b/libpkgconf/path.c @@ -58,6 +58,51 @@ path_list_contains_entry(const char *text, pkgconf_list_t *dirlist) * variables. */ +static pkgconf_path_t * +prepare_path_node(const char *text, pkgconf_list_t *dirlist, bool filter) +{ + pkgconf_path_t *node; + char path[PKGCONF_ITEM_SIZE]; + + pkgconf_strlcpy(path, text, sizeof path); + pkgconf_path_relocate(path, sizeof path); + +#ifdef PKGCONF_CACHE_INODES + struct stat st; + + if (filter) + { + if (lstat(path, &st) == -1) + return NULL; + if (S_ISLNK(st.st_mode)) + { + char pathbuf[PKGCONF_ITEM_SIZE * 4]; + char *linkdest = realpath(path, pathbuf); + + if (linkdest != NULL && stat(linkdest, &st) == -1) + return NULL; + } + if (path_list_contains_entry(path, dirlist, &st)) + return NULL; + } +#else + if (filter && path_list_contains_entry(path, dirlist)) + return NULL; +#endif + + node = calloc(sizeof(pkgconf_path_t), 1); + node->path = strdup(path); + +#ifdef PKGCONF_CACHE_INODES + if (filter) { + node->handle_path = (void *)(intptr_t) st.st_ino; + node->handle_device = (void *)(intptr_t) st.st_dev; + } +#endif + + return node; +} + /* * !doc * @@ -73,44 +118,31 @@ path_list_contains_entry(const char *text, pkgconf_list_t *dirlist) void pkgconf_path_add(const char *text, pkgconf_list_t *dirlist, bool filter) { - pkgconf_path_t *node; - char path[PKGCONF_ITEM_SIZE]; - - pkgconf_strlcpy(path, text, sizeof path); - pkgconf_path_relocate(path, sizeof path); - -#ifdef PKGCONF_CACHE_INODES - struct stat st; - - if (filter) - { - if (lstat(path, &st) == -1) - return; - if (S_ISLNK(st.st_mode)) - { - char pathbuf[PKGCONF_ITEM_SIZE * 4]; - char *linkdest = realpath(path, pathbuf); - - if (linkdest != NULL && stat(linkdest, &st) == -1) - return; - } - if (path_list_contains_entry(path, dirlist, &st)) - return; - } -#else - if (filter && path_list_contains_entry(path, dirlist)) + pkgconf_path_t *node = prepare_path_node(text, dirlist, filter); + if (node == NULL) return; -#endif - node = calloc(sizeof(pkgconf_path_t), 1); - node->path = strdup(path); + pkgconf_node_insert_tail(&node->lnode, node, dirlist); +} -#ifdef PKGCONF_CACHE_INODES - if (filter) { - node->handle_path = (void *)(intptr_t) st.st_ino; - node->handle_device = (void *)(intptr_t) st.st_dev; - } -#endif +/* + * !doc + * + * .. c:function:: void pkgconf_path_prepend(const char *text, pkgconf_list_t *dirlist) + * + * Prepends a path node to a path list. If the path is already in the list, do nothing. + * + * :param char* text: The path text to add as a path node. + * :param pkgconf_list_t* dirlist: The path list to add the path node to. + * :param bool filter: Whether to perform duplicate filtering. + * :return: nothing + */ +void +pkgconf_path_prepend(const char *text, pkgconf_list_t *dirlist, bool filter) +{ + pkgconf_path_t *node = prepare_path_node(text, dirlist, filter); + if (node == NULL) + return; pkgconf_node_insert(&node->lnode, node, dirlist); }