]>
Commit | Line | Data |
---|---|---|
bbc27441 AJ |
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 | ||
582c2af2 | 9 | #include "squid.h" |
57afc994 AR |
10 | |
11 | /* The original code has this constant ./configure-able. | |
12 | * The "#else" branches use raw dlopen interface and have not been tested. | |
26ac0430 | 13 | * We can remove that code if we are going to rely on libtool's ltdl in |
57afc994 AR |
14 | * all environments. */ |
15 | #define XSTD_USE_LIBLTDL 1 | |
16 | ||
17 | #if XSTD_USE_LIBLTDL | |
660faa02 | 18 | #include "libltdl/ltdl.h" /* generated file */ |
57afc994 | 19 | #else |
26ac0430 | 20 | #include <dlfcn.h> |
57afc994 AR |
21 | #endif |
22 | ||
3d93a84d | 23 | #include "base/TextException.h" |
57afc994 AR |
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 | ||
26ac0430 AJ |
29 | LoadableModule::LoadableModule(const String &aName): theName(aName), theHandle(0) |
30 | { | |
57afc994 | 31 | # if XSTD_USE_LIBLTDL |
26ac0430 AJ |
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"); | |
57afc994 AR |
36 | # endif |
37 | } | |
38 | ||
26ac0430 AJ |
39 | LoadableModule::~LoadableModule() |
40 | { | |
41 | if (loaded()) | |
42 | unload(); | |
57afc994 | 43 | # if XSTD_USE_LIBLTDL |
26ac0430 | 44 | assert(lt_dlexit() == 0); // XXX: replace with a warning |
57afc994 AR |
45 | # endif |
46 | } | |
47 | ||
26ac0430 AJ |
48 | bool LoadableModule::loaded() const |
49 | { | |
50 | return theHandle != 0; | |
57afc994 AR |
51 | } |
52 | ||
26ac0430 AJ |
53 | void LoadableModule::load(int mode) |
54 | { | |
55 | if (loaded()) | |
56 | throw TexcHere("internal error: reusing LoadableModule object"); | |
57afc994 | 57 | |
26ac0430 | 58 | theHandle = openModule(mode); |
57afc994 | 59 | |
26ac0430 AJ |
60 | if (!loaded()) |
61 | throw TexcHere(errorMsg()); | |
57afc994 AR |
62 | } |
63 | ||
26ac0430 AJ |
64 | void LoadableModule::unload() |
65 | { | |
66 | if (!loaded()) | |
67 | throw TexcHere("internal error: unloading not loaded module"); | |
57afc994 | 68 | |
26ac0430 AJ |
69 | if (!closeModule()) |
70 | throw TexcHere(errorMsg()); | |
57afc994 | 71 | |
26ac0430 | 72 | theHandle = 0; |
57afc994 AR |
73 | } |
74 | ||
26ac0430 AJ |
75 | void *LoadableModule::openModule(int mode) |
76 | { | |
57afc994 | 77 | # if XSTD_USE_LIBLTDL |
b4f2886c | 78 | return lt_dlopen(theName.termedBuf()); |
57afc994 | 79 | # else |
01cd992f | 80 | return dlopen(theName.termedBuf(), |
26ac0430 | 81 | mode == lmNow ? RTLD_NOW : RTLD_LAZY); |
57afc994 AR |
82 | # endif |
83 | } | |
84 | ||
26ac0430 AJ |
85 | bool LoadableModule::closeModule() |
86 | { | |
57afc994 | 87 | # if XSTD_USE_LIBLTDL |
26ac0430 AJ |
88 | // we cast to avoid including ltdl.h in LoadableModule.h |
89 | return lt_dlclose(static_cast<lt_dlhandle>(theHandle)) == 0; | |
57afc994 | 90 | # else |
26ac0430 | 91 | return dlclose(theHandle) == 0; |
57afc994 AR |
92 | # endif |
93 | } | |
94 | ||
26ac0430 AJ |
95 | const char *LoadableModule::errorMsg() |
96 | { | |
57afc994 | 97 | # if XSTD_USE_LIBLTDL |
26ac0430 | 98 | return lt_dlerror(); |
57afc994 | 99 | # else |
26ac0430 | 100 | return dlerror(); |
57afc994 AR |
101 | # endif |
102 | } |