]>
Commit | Line | Data |
---|---|---|
57afc994 AR |
1 | #include "squid.h" |
2 | ||
3 | /* The original code has this constant ./configure-able. | |
4 | * The "#else" branches use raw dlopen interface and have not been tested. | |
26ac0430 | 5 | * We can remove that code if we are going to rely on libtool's ltdl in |
57afc994 AR |
6 | * all environments. */ |
7 | #define XSTD_USE_LIBLTDL 1 | |
8 | ||
9 | #if XSTD_USE_LIBLTDL | |
660faa02 | 10 | #include "libltdl/ltdl.h" /* generated file */ |
57afc994 | 11 | #else |
26ac0430 | 12 | #include <dlfcn.h> |
57afc994 AR |
13 | #endif |
14 | ||
3d93a84d | 15 | #include "base/TextException.h" |
57afc994 AR |
16 | #include "LoadableModule.h" |
17 | ||
18 | // Note: We must use preprocessor instead of C ifs because if dlopen() | |
19 | // is seen by the static linker, the linker will complain. | |
20 | ||
26ac0430 AJ |
21 | LoadableModule::LoadableModule(const String &aName): theName(aName), theHandle(0) |
22 | { | |
57afc994 | 23 | # if XSTD_USE_LIBLTDL |
26ac0430 AJ |
24 | // Initialise preloaded symbol lookup table. |
25 | LTDL_SET_PRELOADED_SYMBOLS(); | |
26 | if (lt_dlinit() != 0) | |
27 | throw TexcHere("internal error: cannot initialize libtool module loader"); | |
57afc994 AR |
28 | # endif |
29 | } | |
30 | ||
26ac0430 AJ |
31 | LoadableModule::~LoadableModule() |
32 | { | |
33 | if (loaded()) | |
34 | unload(); | |
57afc994 | 35 | # if XSTD_USE_LIBLTDL |
26ac0430 | 36 | assert(lt_dlexit() == 0); // XXX: replace with a warning |
57afc994 AR |
37 | # endif |
38 | } | |
39 | ||
26ac0430 AJ |
40 | bool LoadableModule::loaded() const |
41 | { | |
42 | return theHandle != 0; | |
57afc994 AR |
43 | } |
44 | ||
26ac0430 AJ |
45 | void LoadableModule::load(int mode) |
46 | { | |
47 | if (loaded()) | |
48 | throw TexcHere("internal error: reusing LoadableModule object"); | |
57afc994 | 49 | |
26ac0430 | 50 | theHandle = openModule(mode); |
57afc994 | 51 | |
26ac0430 AJ |
52 | if (!loaded()) |
53 | throw TexcHere(errorMsg()); | |
57afc994 AR |
54 | } |
55 | ||
26ac0430 AJ |
56 | void LoadableModule::unload() |
57 | { | |
58 | if (!loaded()) | |
59 | throw TexcHere("internal error: unloading not loaded module"); | |
57afc994 | 60 | |
26ac0430 AJ |
61 | if (!closeModule()) |
62 | throw TexcHere(errorMsg()); | |
57afc994 | 63 | |
26ac0430 | 64 | theHandle = 0; |
57afc994 AR |
65 | } |
66 | ||
26ac0430 AJ |
67 | void *LoadableModule::openModule(int mode) |
68 | { | |
57afc994 | 69 | # if XSTD_USE_LIBLTDL |
b4f2886c | 70 | return lt_dlopen(theName.termedBuf()); |
57afc994 | 71 | # else |
26ac0430 AJ |
72 | return dlopen(theName.c_str(), |
73 | mode == lmNow ? RTLD_NOW : RTLD_LAZY); | |
57afc994 AR |
74 | # endif |
75 | } | |
76 | ||
26ac0430 AJ |
77 | bool LoadableModule::closeModule() |
78 | { | |
57afc994 | 79 | # if XSTD_USE_LIBLTDL |
26ac0430 AJ |
80 | // we cast to avoid including ltdl.h in LoadableModule.h |
81 | return lt_dlclose(static_cast<lt_dlhandle>(theHandle)) == 0; | |
57afc994 | 82 | # else |
26ac0430 | 83 | return dlclose(theHandle) == 0; |
57afc994 AR |
84 | # endif |
85 | } | |
86 | ||
26ac0430 AJ |
87 | const char *LoadableModule::errorMsg() |
88 | { | |
57afc994 | 89 | # if XSTD_USE_LIBLTDL |
26ac0430 | 90 | return lt_dlerror(); |
57afc994 | 91 | # else |
26ac0430 | 92 | return dlerror(); |
57afc994 AR |
93 | # endif |
94 | } |