summaryrefslogtreecommitdiffhomepage
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.c92
1 files changed, 55 insertions, 37 deletions
diff --git a/src/core/lt_path.c b/src/core/lt_path.c
index 4981b1e..06252a4 100644
--- a/src/core/lt_path.c
+++ b/src/core/lt_path.c
@@ -17,6 +17,7 @@
#include "sltdl_core.h"
#include "sltdl_module.h"
+static int lt_status;
static off_t lt_plen;
static off_t lt_plocs;
static char * lt_upath;
@@ -30,6 +31,12 @@ static struct lt_modctx * lt_modv_tail;
static struct lt_modctx * lt_modv_next;
static struct lt_modctx * lt_modv_cap;
+static int lt_setstatus(int ret, int status)
+{
+ lt_status = status;
+ return ret;
+}
+
const char * lt_dlgetsearchpath(void)
{
return lt_upath;
@@ -44,14 +51,14 @@ static int lt_dlsetsearchpath_locked(const char * path)
off_t elements;
if (path[0] != '/')
- return 1;
+ return lt_setstatus(1,SLTDL_PATH_INVALID_FIRST_CHAR);
elements = 1;
for (ch=&path[1]; *ch; ch++) {
if (*ch == ':') {
if (ch[1] != '/')
- return 1;
+ return lt_setstatus(1,SLTDL_PATH_INVALID_FIRST_CHAR);
elements++;
}
@@ -69,7 +76,7 @@ static int lt_dlsetsearchpath_locked(const char * path)
lt_plocs ^= 0x3f;
if (!(lt_pathv = calloc(lt_plocs,sizeof(char *))))
- return 1;
+ return lt_setstatus(1,SLTDL_SYSTEM_ERROR);
}
if ((ch - path) > lt_plen) {
@@ -84,9 +91,8 @@ static int lt_dlsetsearchpath_locked(const char * path)
lt_plen += 0x7ff;
lt_plen |= 0x7ff;
lt_plen ^= 0x7ff;
-
if (!(lt_upath = calloc(2*lt_plen,1)))
- return 1;
+ return lt_setstatus(1,SLTDL_SYSTEM_ERROR);
lt_vpath = &lt_upath[lt_plen];
}
@@ -113,16 +119,18 @@ static int lt_dlsetsearchpath_locked(const char * path)
lt_vmark = pathv;
- return 0;
+ return lt_setstatus(0,SLTDL_OK);
}
int lt_dlsetsearchpath(const char * path)
{
+ int ret;
lt_slock();
- return lt_sunlock(lt_dlsetsearchpath_locked(path));
+ ret = lt_dlsetsearchpath_locked(path);
+ return lt_sunlock(ret,lt_status);
}
-int lt_dladdsearchdir(const char * path)
+static int lt_dladdsearchdir_locked(const char * path)
{
int ret;
const char * ch;
@@ -131,13 +139,11 @@ int lt_dladdsearchdir(const char * path)
off_t plen;
if (path[0] != '/')
- return 1;
+ return lt_setstatus(1,SLTDL_PATH_INVALID_FIRST_CHAR);
for (ch=path; *ch; ch++)
if (*ch == ':')
- return 1;
-
- lt_slock();
+ return lt_setstatus(1,SLTDL_PATH_INVALID_SEPARATTOR_CHAR);
alen = strlen(path);
plen = strlen(lt_upath);
@@ -154,12 +160,12 @@ int lt_dladdsearchdir(const char * path)
*lt_vmark++ = &lt_vpath[plen];
- return lt_sunlock(0);
+ return lt_setstatus(0,SLTDL_OK);
}
/* (allocation needed) */
if (!(buf = malloc(plen + 1 + alen + 1)))
- return lt_sunlock(1);
+ return lt_setstatus(1,SLTDL_SYSTEM_ERROR);
sprintf(buf,"%s:%s",lt_upath,path);
@@ -167,7 +173,15 @@ int lt_dladdsearchdir(const char * path)
free(buf);
- return lt_sunlock(ret);
+ return ret;
+}
+
+int lt_dladdsearchdir(const char * path)
+{
+ int ret;
+ lt_slock();
+ ret = lt_dladdsearchdir_locked(path);
+ return lt_sunlock(ret,lt_status);
}
int lt_dlinsertsearchdir(const char * mark, const char * path)
@@ -182,26 +196,26 @@ int lt_dlinsertsearchdir(const char * mark, const char * path)
off_t offset;
char ** pathv;
- if (path[0] != '/')
- return 1;
-
if (!mark)
return lt_dladdsearchdir(path);
+ lt_slock();
+
+ if (path[0] != '/')
+ return lt_sunlock(1,SLTDL_PATH_INVALID_FIRST_CHAR);
+
for (ch=path; *ch; ch++)
if (*ch == ':')
- return 1;
-
- lt_slock();
+ return lt_sunlock(1,SLTDL_PATH_INVALID_SEPARATTOR_CHAR);
alen = strlen(path);
plen = strlen(lt_upath);
if ((mark < lt_upath) || (mark >= &lt_upath[plen]))
- return lt_sunlock(1);
+ return lt_sunlock(1,SLTDL_PATH_INVALID_MARK);
if ((mark > lt_upath) && (mark[-1] != ':'))
- return lt_sunlock(1);
+ return lt_sunlock(1,SLTDL_PATH_INVALID_MARK);
mark = &lt_vpath[mark - lt_upath];
@@ -226,14 +240,14 @@ int lt_dlinsertsearchdir(const char * mark, const char * path)
memcpy(&lt_upath[offset],path,alen);
lt_upath[offset+alen] = ':';
lt_vmark++;
- return lt_sunlock(0);
+ return lt_sunlock(0,SLTDL_OK);
}
}
}
/* (allocation needed) */
if (!(buf = malloc(plen + 1 + alen + 1)))
- return lt_sunlock(1);
+ return lt_sunlock(1,SLTDL_SYSTEM_ERROR);
for (dst=buf, pathv=lt_pathv; *pathv; pathv++) {
if (*pathv == mark)
@@ -249,7 +263,7 @@ int lt_dlinsertsearchdir(const char * mark, const char * path)
free(buf);
- return lt_sunlock(ret);
+ return lt_sunlock(ret,lt_status);
}
static int lt_dlpathopen_locked(
@@ -267,7 +281,7 @@ static int lt_dlpathopen_locked(
char path[1024];
if ((mlen = strlen(module)) >= sizeof(path))
- return -1;
+ return lt_setstatus(-1,SLTDL_PATH_INVALID_LEN);
memcpy(path,module,mlen);
@@ -278,7 +292,7 @@ static int lt_dlpathopen_locked(
for (pext=extv; *pext; pext++) {
if (mlen + (elen = strlen(*pext)) >= (sizeof(path))) {
close(fdat);
- return (-1);
+ return lt_setstatus(-1,SLTDL_PATH_INVALID_LEN);
}
memcpy(&path[mlen],*pext,elen);
@@ -294,14 +308,14 @@ static int lt_dlpathopen_locked(
if (!(*mpath = malloc(plen))) {
close(fdat);
close(fdmod);
- return (-1);
+ return lt_setstatus(-1,SLTDL_SYSTEM_ERROR);
}
sprintf(*mpath,"%s/%s",*ppath,path);
}
close(fdat);
- return fdmod;
+ return lt_setstatus(fdmod,SLTDL_OK);
}
}
@@ -309,13 +323,15 @@ static int lt_dlpathopen_locked(
}
}
- return -1;
+ return lt_setstatus(-1,SLTDL_PATH_NO_ENTRY);
}
int lt_dlpathopen(const char * module, const char ** extv)
{
+ int ret;
lt_slock();
- return lt_sunlock(lt_dlpathopen_locked(module,extv,0));
+ ret = lt_dlpathopen_locked(module,extv,0);
+ return lt_sunlock(ret,lt_status);
}
static struct lt_modctx * lt_dlopen_locked(
@@ -339,6 +355,7 @@ static struct lt_modctx * lt_dlopen_locked(
if (lt_modv_next == lt_modv_cap) {
if (!(modctx_buf = calloc(64,sizeof(*modctx)))) {
free(mpath);
+ lt_setstatus(0,SLTDL_SYSTEM_ERROR);
return 0;
}
@@ -349,6 +366,7 @@ static struct lt_modctx * lt_dlopen_locked(
/* dlopen */
if (!(maddr = dlopen(mpath,mode))) {
free(mpath);
+ lt_setstatus(0,SLTDL_DLFCN_ERROR);
return 0;
}
@@ -388,7 +406,7 @@ struct lt_modctx * lt_dlopen(const char * module)
lt_slock();
modctx = lt_dlopen_locked(module,extv,RTLD_NOW);
- lt_sunlock(0);
+ lt_sunlock(0,lt_status);
return modctx;
}
@@ -399,7 +417,7 @@ struct lt_modctx * lt_dlopenext(const char * module)
lt_slock();
modctx = lt_dlopen_locked(module,extv,RTLD_NOW);
- lt_sunlock(0);
+ lt_sunlock(0,lt_status);
return modctx;
}
@@ -424,12 +442,12 @@ int lt_dlclose(struct lt_modctx * modctx)
if (pmod == modctx) {
if (pmod->mrefs) {
pmod->mrefs--;
- return lt_sunlock(0);
+ return lt_sunlock(0,SLTDL_OK);
}
- return lt_sunlock(-1);
+ return lt_sunlock(-1,SLTDL_MODULE_REF_COUNT);
}
}
- return lt_sunlock(-1);
+ return lt_sunlock(-1,SLTDL_MODULE_PTR_INVALID);
}