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