diff --git a/include/sltdl/sltdl.h b/include/sltdl/sltdl.h index a65fe8b..bd0b5bb 100644 --- a/include/sltdl/sltdl.h +++ b/include/sltdl/sltdl.h @@ -27,6 +27,7 @@ lt_api int lt_dlinit(void); lt_api int lt_dlexit(void); /* library search path */ +lt_api int lt_dlpathopen(const char *, const char **); lt_api int lt_dladdsearchdir(const char *); lt_api int lt_dlinsertsearchdir(const char *, const char *); lt_api int lt_dlsetsearchpath(const char *); diff --git a/src/core/lt_path.c b/src/core/lt_path.c index 14eb0eb..5d58b03 100644 --- a/src/core/lt_path.c +++ b/src/core/lt_path.c @@ -5,9 +5,11 @@ /*******************************************************************/ #include +#include #include #include #include +#include #include #include #include "sltdl_core.h" @@ -240,3 +242,48 @@ int lt_dlinsertsearchdir(const char * mark, const char * path) return lt_sunlock(ret); } + +int lt_dlpathopen(const char * module, const char ** extv) +{ + int fdat; + int fdmod; + char ** ppath; + const char ** pext; + size_t mlen; + size_t elen; + char path[1024]; + + if ((mlen = strlen(module)) >= sizeof(path)) + return -1; + + memcpy(path,module,mlen); + + lt_slock(); + + for (ppath=lt_pathv; *ppath; ppath++) { + fdat = open(*ppath,O_RDONLY|O_DIRECTORY|O_CLOEXEC,0); + + if (fdat >= 0) { + for (pext=extv; *pext; pext++) { + if (mlen + (elen = strlen(*pext)) >= (sizeof(path))) { + close(fdat); + return (-1); + } + + memcpy(&path[mlen],*pext,elen); + path[mlen+elen] = 0; + + fdmod = openat(fdat,path,O_EXEC|O_CLOEXEC,0); + + if (fdmod >= 0) { + close(fdat); + return lt_sunlock(fdmod); + } + } + + close(fdat); + } + } + + return lt_sunlock(-1); +}