aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAurélien Aptel2015-11-16 00:36:35 +0100
committerTed Zlatanov2015-11-18 14:23:53 -0500
commit435cf35bcc28ab4220764dff7874f477310d9a48 (patch)
tree1d0eabdd58b93d90efc424690f830e6a7d0243e1 /src
parent7cdc5d628a737e2153c38d0d285c9879071beaa7 (diff)
downloademacs-435cf35bcc28ab4220764dff7874f477310d9a48.tar.gz
emacs-435cf35bcc28ab4220764dff7874f477310d9a48.zip
Add portable layer for dynamic loading
* src/dynlib.h: New file. * src/dynlib.c: New file. Co-authored-by: Philipp Stephani <phst@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/dynlib.c93
-rw-r--r--src/dynlib.h14
2 files changed, 107 insertions, 0 deletions
diff --git a/src/dynlib.c b/src/dynlib.c
new file mode 100644
index 00000000000..f9478099169
--- /dev/null
+++ b/src/dynlib.c
@@ -0,0 +1,93 @@
1/*
2 * Portable API for dynamic loading
3 *
4 * Assuming modules are enabled on modern systems... *Yes*, the
5 * preprocessor macro checks could be more precise. I don't care.
6 *
7 * If you think the abstraction is too leaky use libltdl (libtool),
8 * don't reinvent the wheel by fixing this one.
9 */
10
11#include "dynlib.h"
12
13/*
14 * Windows systems
15 */
16#if defined(_WIN32)
17
18#include <windows.h>
19
20dynlib_handle_ptr dynlib_open (const char * path)
21{
22
23 return (dynlib_handle_ptr) LoadLibrary (path);
24}
25
26void * dynlib_sym (dynlib_handle_ptr h, const char * sym)
27{
28 return GetProcAddress ((HMODULE) h, sym);
29}
30
31bool dynlib_addr (void *ptr, const char **path, const char **sym)
32{
33 return false; /* not implemented */
34}
35
36const char * dynlib_error (void)
37{
38 /* TODO: use GetLastError(), FormatMessage(), ... */
39 return "Can't load DLL";
40}
41
42int dynlib_close (dynlib_handle_ptr h)
43{
44 return FreeLibrary ((HMODULE) h) != 0;
45}
46
47
48/*
49 * POSIX systems
50 */
51#elif defined(HAVE_UNISTD_H)
52
53#include <dlfcn.h>
54
55dynlib_handle_ptr dynlib_open (const char * path)
56{
57 return dlopen (path, RTLD_LAZY);
58}
59
60void * dynlib_sym (dynlib_handle_ptr h, const char * sym)
61{
62 return dlsym (h, sym);
63}
64
65bool dynlib_addr (void *ptr, const char **path, const char **sym)
66{
67#ifdef HAVE_DLADDR
68 Dl_info info;
69 if (dladdr (ptr, &info) != 0 && info.dli_fname != NULL && info.dli_sname != NULL)
70 {
71 *path = info.dli_fname;
72 *sym = info.dli_sname;
73 return true;
74 }
75#endif
76 return false;
77}
78
79const char * dynlib_error (void)
80{
81 return dlerror ();
82}
83
84int dynlib_close (dynlib_handle_ptr h)
85{
86 return dlclose (h) == 0;
87}
88
89#else
90
91#error "No dynamic loading for this system"
92
93#endif
diff --git a/src/dynlib.h b/src/dynlib.h
new file mode 100644
index 00000000000..229fc960221
--- /dev/null
+++ b/src/dynlib.h
@@ -0,0 +1,14 @@
1#ifndef DYNLIB_H
2#define DYNLIB_H
3
4#include <config.h>
5#include <stdbool.h>
6
7typedef void* dynlib_handle_ptr;
8dynlib_handle_ptr dynlib_open (const char * path);
9void * dynlib_sym (dynlib_handle_ptr h, const char * sym);
10bool dynlib_addr (void *ptr, const char **path, const char **sym);
11const char * dynlib_error (void);
12int dynlib_close (dynlib_handle_ptr h);
13
14#endif /* DYNLIB_H */