diff options
author | José Bollo <jose.bollo@iot.bzh> | 2017-09-06 18:15:17 +0200 |
---|---|---|
committer | José Bollo <jose.bollo@iot.bzh> | 2017-09-07 10:02:36 +0200 |
commit | c4c474c056cd070706d5a3b0af7845c9493bfdaf (patch) | |
tree | 548b381f88dd49a490cb1153d8da09ce1bec5f57 | |
parent | e2ad3e670ac79f5271ce7273368610d7130ac167 (diff) |
In some case, dlopen raise a segmentation fault.
This commit takes care of this.
Change-Id: I6cbe59de2422dafcdf3714d0539b1757511c100b
Bug-AGL: SPEC-662
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
-rw-r--r-- | src/afb-api-so.c | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/src/afb-api-so.c b/src/afb-api-so.c index bee5fe80..5a7f29cf 100644 --- a/src/afb-api-so.c +++ b/src/afb-api-so.c @@ -28,6 +28,35 @@ #include "afb-api-so-v1.h" #include "afb-api-so-v2.h" #include "verbose.h" +#include "sig-monitor.h" + +struct safe_dlopen +{ + const char *path; + void *handle; + int flags; +}; + +static void safe_dlopen_cb(int sig, void *closure) +{ + struct safe_dlopen *sd = closure; + if (!sig) + sd->handle = dlopen(sd->path, sd->flags); + else { + ERROR("dlopen of %s raised signal %s", sd->path, strsignal(sig)); + sd->handle = NULL; + } +} + +static void *safe_dlopen(const char *filename, int flags) +{ + struct safe_dlopen sd; + sd.path = filename; + sd.flags = flags; + sd.handle = NULL; + sig_monitor(0, safe_dlopen_cb, &sd); + return sd.handle; +} static int load_binding(const char *path, int force, struct afb_apiset *apiset) { @@ -36,7 +65,7 @@ static int load_binding(const char *path, int force, struct afb_apiset *apiset) // This is a loadable library let's check if it's a binding rc = -!!force; - handle = dlopen(path, RTLD_NOW | RTLD_LOCAL); + handle = safe_dlopen(path, RTLD_NOW | RTLD_LOCAL); if (handle == NULL) { if (force) ERROR("binding [%s] not loadable: %s", path, dlerror()); @@ -116,9 +145,9 @@ static int adddirs(char path[PATH_MAX], size_t end, struct afb_apiset *apiset) /* case of directories */ if (dent->d_name[0] == '.') { if (len == 1) - continue; + continue; /* . */ if (dent->d_name[1] == '.' && len == 2) - continue; + continue; /* .. */ } memcpy(&path[end], dent->d_name, len+1); adddirs(path, end+len, apiset); |