diff options
Diffstat (limited to 'src/core/lt_path.c')
-rw-r--r-- | src/core/lt_path.c | 35 |
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 = <_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; |