]> git.ipfire.org Git - thirdparty/squid.git/blob - src/LoadableModule.cc
996797efc3e84c7c2f2a8282b51d579f627385d0
[thirdparty/squid.git] / src / LoadableModule.cc
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.
5 * We can remove that code if we are going to rely on libtool's ltdl in
6 * all environments. */
7 #define XSTD_USE_LIBLTDL 1
8
9 #if XSTD_USE_LIBLTDL
10 #include "libltdl/ltdl.h" /* generated file */
11 #else
12 #include <dlfcn.h>
13 #endif
14
15 #include "base/TextException.h"
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
21 LoadableModule::LoadableModule(const String &aName): theName(aName), theHandle(0)
22 {
23 # if XSTD_USE_LIBLTDL
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");
28 # endif
29 }
30
31 LoadableModule::~LoadableModule()
32 {
33 if (loaded())
34 unload();
35 # if XSTD_USE_LIBLTDL
36 assert(lt_dlexit() == 0); // XXX: replace with a warning
37 # endif
38 }
39
40 bool LoadableModule::loaded() const
41 {
42 return theHandle != 0;
43 }
44
45 void LoadableModule::load(int mode)
46 {
47 if (loaded())
48 throw TexcHere("internal error: reusing LoadableModule object");
49
50 theHandle = openModule(mode);
51
52 if (!loaded())
53 throw TexcHere(errorMsg());
54 }
55
56 void LoadableModule::unload()
57 {
58 if (!loaded())
59 throw TexcHere("internal error: unloading not loaded module");
60
61 if (!closeModule())
62 throw TexcHere(errorMsg());
63
64 theHandle = 0;
65 }
66
67 void *LoadableModule::openModule(int mode)
68 {
69 # if XSTD_USE_LIBLTDL
70 return lt_dlopen(theName.termedBuf());
71 # else
72 return dlopen(theName.termedBuf(),
73 mode == lmNow ? RTLD_NOW : RTLD_LAZY);
74 # endif
75 }
76
77 bool LoadableModule::closeModule()
78 {
79 # if XSTD_USE_LIBLTDL
80 // we cast to avoid including ltdl.h in LoadableModule.h
81 return lt_dlclose(static_cast<lt_dlhandle>(theHandle)) == 0;
82 # else
83 return dlclose(theHandle) == 0;
84 # endif
85 }
86
87 const char *LoadableModule::errorMsg()
88 {
89 # if XSTD_USE_LIBLTDL
90 return lt_dlerror();
91 # else
92 return dlerror();
93 # endif
94 }