From bad0da0c03cc8e34f2f3459db0931efe8d8e9eee Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Fri, 30 Dec 2016 11:01:15 -0600 Subject: [PATCH] libpkgconf: path: filter out duplicate path entries by inode if possible (closes #102) --- libpkgconf/libpkgconf.h | 1 + libpkgconf/path.c | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/libpkgconf/libpkgconf.h b/libpkgconf/libpkgconf.h index 98e1345..e88792e 100644 --- a/libpkgconf/libpkgconf.h +++ b/libpkgconf/libpkgconf.h @@ -92,6 +92,7 @@ struct pkgconf_path_ { pkgconf_node_t lnode; char *path; + void *handle; }; #define PKGCONF_PKG_PROPF_NONE 0x0 diff --git a/libpkgconf/path.c b/libpkgconf/path.c index b25407c..bb3250d 100644 --- a/libpkgconf/path.c +++ b/libpkgconf/path.c @@ -16,8 +16,17 @@ #include #include +#ifdef HAVE_SYS_STAT_H +# include +# define PKGCONF_CACHE_INODES +#endif + static bool +#ifdef PKGCONF_CACHE_INODES +path_list_contains_entry(const char *text, pkgconf_list_t *dirlist, struct stat *st) +#else path_list_contains_entry(const char *text, pkgconf_list_t *dirlist) +#endif { pkgconf_node_t *n; @@ -25,6 +34,11 @@ path_list_contains_entry(const char *text, pkgconf_list_t *dirlist) { pkgconf_path_t *pn = n->data; +#ifdef PKGCONF_CACHE_INODES + if (((ino_t) pn->handle) == st->st_ino) + return true; +#endif + if (!strcmp(text, pn->path)) return true; } @@ -58,12 +72,24 @@ void pkgconf_path_add(const char *text, pkgconf_list_t *dirlist) { pkgconf_path_t *node; +#ifdef PKGCONF_CACHE_INODES + struct stat st; + if (stat(text, &st) == -1) + return; + + if (path_list_contains_entry(text, dirlist, &st)) + return; +#else if (path_list_contains_entry(text, dirlist)) return; +#endif node = calloc(sizeof(pkgconf_path_t), 1); node->path = strdup(text); +#ifdef PKGCONF_CACHE_INODES + node->handle = (void *)(intptr_t) st.st_ino; +#endif pkgconf_node_insert_tail(&node->lnode, node, dirlist); }