summaryrefslogtreecommitdiff
path: root/src/core/lt_path.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/lt_path.c')
-rw-r--r--src/core/lt_path.c35
1 files changed, 24 insertions, 11 deletions
diff --git a/src/core/lt_path.c b/src/core/lt_path.c
index 2017a95..fee9522 100644
--- a/src/core/lt_path.c
+++ b/src/core/lt_path.c
@@ -375,10 +375,16 @@ static struct lt_modctx * lt_dlopen_locked(
/* path open (module) */
if (module) {
- if ((fdmod = lt_dlpathopen_locked(module,extv,&mpath)) < 0)
- return 0;
+ fdmod = lt_dlpathopen_locked(
+ module,extv,&mpath);
+
+ if (fdmod >= 0) {
+ close(fdmod);
- close(fdmod);
+ } else if (!(mpath = strdup(module))) {
+ lt_setstatus(0,SLTDL_ERR_SYSTEM_ERROR);
+ return 0;
+ }
}
/* entry alloc */
@@ -393,22 +399,27 @@ static struct lt_modctx * lt_dlopen_locked(
lt_modv_cap = &lt_modv_next[64];
}
- /* dlopen (module) */
- if (module && !(maddr = dlopen(mpath,mode))) {
+ /* dlopen (module), dlopen (self) */
+ if (!symtbl && !(maddr = dlopen(mpath,mode))) {
free(mpath);
lt_setstatus(0,SLTDL_ERR_DLFCN_ERROR);
return 0;
}
/* module already dlopen'ed? */
- for (modctx=lt_modv_head; module && modctx; modctx=modctx->mnext) {
- if (!strcmp(modctx->mpath,mpath)) {
+ for (modctx=lt_modv_head; maddr && modctx; modctx=modctx->mnext) {
+ if (modctx->maddr == maddr) {
free(mpath);
modctx->mrefs++;
return modctx;
}
}
+ /* symbol table already preloaded? */
+ for (modctx=lt_modv_head; symtbl && modctx; modctx=modctx->mnext)
+ if (modctx->symtbl == symtbl)
+ return modctx;
+
/* module or symtbl entry */
modctx = lt_modv_next;
modctx->symtbl = symtbl;
@@ -440,13 +451,16 @@ struct lt_modctx * lt_dlopen(const char * module)
lt_slock();
- if ((slen = strlen(module)) >= PATH_MAX) {
+ if (module && (slen = strlen(module)) >= PATH_MAX) {
lt_setstatus(0,SLTDL_ERR_SYSTEM_ERROR);
lt_sunlock(0,lt_status);
return 0;
}
- strcpy(dsobuf,module);
+ if (module) {
+ strcpy(dsobuf,module);
+ module = dsobuf;
+ }
if ((dot = strrchr(dsobuf,'.')))
if (!strcmp(dot,".la"))
@@ -454,7 +468,6 @@ struct lt_modctx * lt_dlopen(const char * module)
if (PATH_MAX - slen > strlen(OS_LIB_SUFFIX))
strcpy(dot,OS_LIB_SUFFIX);
- module = dsobuf;
modctx = lt_dlopen_locked(0,module,extv,RTLD_NOW);
lt_sunlock(0,lt_status);
return modctx;
@@ -648,7 +661,7 @@ static int lt_dlpreload_modctl_locked(
? 0 : -1;
case SLTDL_MODCTL_PRELOAD_DEFAULT:
- if (!(modctx = lt_dlopen_locked(symtbl,0,0,(-1))))
+ if (!(modctx = lt_dlopen_locked(symtbl,0,0,0)))
return -1;
modctx->mrefs = -1;