diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/lt_path.c | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/src/core/lt_path.c b/src/core/lt_path.c index d3f7ec1..c4e4793 100644 --- a/src/core/lt_path.c +++ b/src/core/lt_path.c @@ -4,8 +4,10 @@ /* Released under the Standard MIT License; see COPYING.SLTDL. */ /*******************************************************************/ +#include <glob.h> #include <limits.h> #include <dlfcn.h> +#include <errno.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> @@ -491,3 +493,86 @@ int lt_dlclose(struct lt_modctx * modctx) return lt_sunlock(-1,SLTDL_MODULE_PTR_INVALID); } + +static int lt_dlforeachfile_one( + const char * path, + int (*fusr)(const char * direntry, void * data), + void * data) +{ + int ret; + char ** argv; + glob_t globbuf; + char pathbuf[PATH_MAX]; + + globbuf.gl_pathc = 0; + globbuf.gl_pathv = 0; + globbuf.gl_offs = 0; + + ret = snprintf( + pathbuf, + sizeof(pathbuf), + "%s/" "*" OS_LIB_SUFFIX, + path); + + if (ret >= PATH_MAX) { + errno = EINVAL; + return -1; + } + + if ((ret = glob(pathbuf,0,0,&globbuf)) < 0) + return ret; + + for (argv=globbuf.gl_pathv; argv && *argv; argv++) { + if ((ret = fusr(*argv,data))) { + globfree(&globbuf); + return ret; + } + } + + globfree(&globbuf); + + return 0; +} + +int lt_dlforeachfile( + const char * path, + int (*fusr)(const char * direntry, void * data), + void * data) +{ + int ret; + char ** pathv; + char * spath; + char * mark; + char * ch; + + if (path) { + if (!(spath = strdup(path))) + return -1; + + mark = spath; + ch = spath; + + for (; *ch; ) { + for (ch=mark; ch[0] && ch[0] != ':'; ch++) + (void)0; + + if (ch[0]) + *ch++ = '\0'; + + if ((ret = lt_dlforeachfile_one(mark,fusr,data))) { + free(spath); + return ret; + } + + mark = ch; + } + + free(spath); + } else { + for (pathv=lt_pathv; pathv && *pathv; pathv++) + if ((ret = lt_dlforeachfile_one(*pathv,fusr,data))) + return ret; + } + + return 0; +} |