From 8744a55869e9d0288bebf8f340d5186dc99922e9 Mon Sep 17 00:00:00 2001 From: midipix Date: Sat, 21 Dec 2019 14:40:23 +0000 Subject: lt_dlerror(): initial implementation and integration. --- src/core/lt_core.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 77 insertions(+), 3 deletions(-) (limited to 'src/core/lt_core.c') diff --git a/src/core/lt_core.c b/src/core/lt_core.c index df9f58f..8c26ff3 100644 --- a/src/core/lt_core.c +++ b/src/core/lt_core.c @@ -4,12 +4,36 @@ /* Released under the Standard MIT License; see COPYING.SLTDL. */ /*******************************************************************/ +#include +#include #include +#include +#include #include + #include +#include "sltdl_core.h" + +static const char * lt_dlerror_desc[] = { + [SLTDL_OK] = 0, + [SLTDL_SYSTEM_ERROR] = 0, + [SLTDL_DLFCN_ERROR] = 0, + [SLTDL_SLTDL_ERROR] = "sltdl internal error", + [SLTDL_DLEXIT_REF_COUNT] = "lt_dlexit() reference count already zero", + [SLTDL_MODULE_REF_COUNT] = "module reference count already zero", + [SLTDL_MODULE_PTR_INVALID] = "module handle invalid", + [SLTDL_PATH_INVALID_FIRST_CHAR] = "invalid path (does not begin with a forward slash)", + [SLTDL_PATH_INVALID_SEPARATTOR_CHAR] = "invalid path (separator character is not a colon)", + [SLTDL_PATH_INVALID_MARK] = "invalid path (mark not within range)", + [SLTDL_PATH_INVALID_LEN] = "invalid path (string too long)", + [SLTDL_PATH_NO_ENTRY] = "invalid path (not found)", +}; -static int lt_refs = 0; -static pthread_mutex_t lt_lock = PTHREAD_MUTEX_INITIALIZER; +static int lt_refs = 0; +static int lt_error = 0; +static int lt_errno = 0; +static char * lt_dlerr = 0; +static pthread_mutex_t lt_lock = PTHREAD_MUTEX_INITIALIZER; int lt_dlinit(void) { @@ -28,6 +52,7 @@ int lt_dlexit(void) return 1; if (!lt_refs) { + lt_error = SLTDL_DLEXIT_REF_COUNT; pthread_mutex_unlock(<_lock); return 1; } @@ -48,8 +73,57 @@ void lt_slock(void) } while (locked); } -int lt_sunlock(int ret) +int lt_sunlock(int ret, int error) { + if (error == 0) { + pthread_mutex_unlock(<_lock); + return 0; + } + + if ((error < 0) || (error >= SLTDL_ERROR_CAP)) { + error = SLTDL_SLTDL_ERROR; + + } else if (error == SLTDL_SYSTEM_ERROR) { + lt_errno = errno; + + } else if (error == SLTDL_DLFCN_ERROR) { + if (lt_dlerr) + free(lt_dlerr); + + lt_dlerr = strdup(dlerror()); + } + + lt_error = error; pthread_mutex_unlock(<_lock); return ret; } + +const char * lt_dlerror(void) +{ + const char * errdesc; + + lt_slock(); + + switch (lt_error) { + case SLTDL_OK: + errdesc = 0; + break; + + case SLTDL_SYSTEM_ERROR: + errdesc = strerror(lt_errno); + break; + + case SLTDL_DLFCN_ERROR: + errdesc = lt_dlerr; + break; + + default: + errdesc = lt_dlerror_desc[lt_error]; + break; + } + + lt_error = 0; + lt_sunlock(0,0); + + return errdesc; +} -- cgit v1.2.3