summaryrefslogtreecommitdiffstats
path: root/sysif.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-05-03 22:14:41 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-05-03 22:14:41 -0700
commit90f5aae6185214f77c8566500a94af264015b60b (patch)
tree54e0085efebb5ed9c777dc836870a4a59bd6743e /sysif.c
parentcadecad595dde6766e1883d1c598ffa5dc58999d (diff)
downloadtxr-90f5aae6185214f77c8566500a94af264015b60b.tar.gz
txr-90f5aae6185214f77c8566500a94af264015b60b.tar.bz2
txr-90f5aae6185214f77c8566500a94af264015b60b.zip
dlopen: add error reporting via dlerror()
* sysif.c (dlopen_wrap): Call dlerror() to clear the error string. Then if the call returns null, call dlerror() again and use the string in the exception if available. (dlsym_error): New static function. (dlsym_checked, dlvsym_checked): Clear error string by calling dlerror(). Afer the call, if the pointer is null call dlsym_error to report.
Diffstat (limited to 'sysif.c')
-rw-r--r--sysif.c31
1 files changed, 22 insertions, 9 deletions
diff --git a/sysif.c b/sysif.c
index b7fceae9..4eb5c1b7 100644
--- a/sysif.c
+++ b/sysif.c
@@ -1479,10 +1479,15 @@ static val dlopen_wrap(val name, val flags)
0, c_str(name));
char *name_u8 = if3(name_ws != 0, utf8_dup_to(name_ws), 0);
cnum f = if3(missingp(flags), RTLD_LAZY, c_num(flags));
- mem_t *ptr = coerce(mem_t *, dlopen(name_u8, f));
+ mem_t *ptr = coerce(mem_t *, (dlerror(), dlopen(name_u8, f)));
free(name_u8);
- if (ptr == 0)
- uw_throwf(error_s, lit("dlopen failed on ~a"), name, nao);
+ if (ptr == 0) {
+ char *err = dlerror();
+ if (err)
+ uw_throwf(error_s, lit("dlopen failed: ~a"), string_utf8(err), nao);
+ else
+ uw_throwf(error_s, lit("dlopen failed on ~a"), name, nao);
+ }
return cobj(ptr, cptr_s, &cptr_dl_ops);
}
@@ -1510,12 +1515,21 @@ static val dlsym_wrap(val dlptr, val name)
return cptr(sym);
}
+static void dlsym_error(val dlptr, val name, val self)
+{
+ char *err = dlerror();
+ if (err)
+ uw_throwf(error_s, lit("~a: ~a"), self, string_utf8(err), nao);
+ else
+ uw_throwf(error_s, lit("~a: ~a not found in ~s"),
+ self, name, dlptr, nao);
+}
+
static val dlsym_checked(val dlptr, val name)
{
- val ptr = dlsym_wrap(dlptr, name);
+ val ptr = (dlerror(), dlsym_wrap(dlptr, name));
if (cptr_get(ptr) == 0)
- uw_throwf(error_s, lit("dlsym: ~s not found in ~s"),
- name, dlptr, nao);
+ dlsym_error(dlptr, name, lit("dlsym-checked"));
return ptr;
}
@@ -1539,10 +1553,9 @@ static val dlvsym_wrap(val dlptr, val name, val ver)
static val dlvsym_checked(val dlptr, val name, val ver)
{
- val ptr = dlvsym_wrap(dlptr, name, ver);
+ val ptr = (dlerror(), dlvsym_wrap(dlptr, name, ver));
if (cptr_get(ptr) == 0)
- uw_throwf(error_s, lit("dlvsym: ~s not found in ~s"),
- name, dlptr, nao);
+ dlsym_error(dlptr, name, lit("dlvsym-checked"));
return ptr;
}
#endif