xref: /aosp_15_r20/external/libxml2/xmlmodule.c (revision 7c5688314b92172186c154356a6374bf7684c3ca)
1 /*
2  * xmlmodule.c : basic API for dynamic module loading added 2.6.17
3  *
4  * See Copyright for the status of this software.
5  *
6  * [email protected]
7  *
8  * http://www.fortran-2000.com/ArnaudRecipes/sharedlib.html
9  */
10 
11 /* In order RTLD_GLOBAL and RTLD_NOW to be defined on zOS */
12 #if defined(__MVS__)
13 #define _UNIX03_SOURCE
14 #endif
15 
16 #define IN_LIBXML
17 #include "libxml.h"
18 
19 #include <string.h>
20 #include <libxml/xmlmodule.h>
21 #include <libxml/xmlmemory.h>
22 #include <libxml/xmlerror.h>
23 #include <libxml/xmlstring.h>
24 
25 #include "private/error.h"
26 
27 #ifdef LIBXML_MODULES_ENABLED
28 
29 struct _xmlModule {
30     unsigned char *name;
31     void *handle;
32 };
33 
34 static void *xmlModulePlatformOpen(const char *name);
35 static int xmlModulePlatformClose(void *handle);
36 static int xmlModulePlatformSymbol(void *handle, const char *name, void **result);
37 
38 /************************************************************************
39  *									*
40  *		module memory error handler				*
41  *									*
42  ************************************************************************/
43 
44 /**
45  * xmlModuleOpen:
46  * @name: the module name
47  * @options: a set of xmlModuleOption
48  *
49  * Opens a module/shared library given its name or path
50  * NOTE: that due to portability issues, behaviour can only be
51  * guaranteed with @name using ASCII. We cannot guarantee that
52  * an UTF-8 string would work, which is why name is a const char *
53  * and not a const xmlChar * .
54  * TODO: options are not yet implemented.
55  *
56  * Returns a handle for the module or NULL in case of error
57  */
58 xmlModulePtr
xmlModuleOpen(const char * name,int options ATTRIBUTE_UNUSED)59 xmlModuleOpen(const char *name, int options ATTRIBUTE_UNUSED)
60 {
61     xmlModulePtr module;
62 
63     module = (xmlModulePtr) xmlMalloc(sizeof(xmlModule));
64     if (module == NULL)
65         return (NULL);
66 
67     memset(module, 0, sizeof(xmlModule));
68 
69     module->handle = xmlModulePlatformOpen(name);
70 
71     if (module->handle == NULL) {
72         xmlFree(module);
73         return(NULL);
74     }
75 
76     module->name = xmlStrdup((const xmlChar *) name);
77     return (module);
78 }
79 
80 /**
81  * xmlModuleSymbol:
82  * @module: the module
83  * @name: the name of the symbol
84  * @symbol: the resulting symbol address
85  *
86  * Lookup for a symbol address in the given module
87  * NOTE: that due to portability issues, behaviour can only be
88  * guaranteed with @name using ASCII. We cannot guarantee that
89  * an UTF-8 string would work, which is why name is a const char *
90  * and not a const xmlChar * .
91  *
92  * Returns 0 if the symbol was found, or -1 in case of error
93  */
94 int
xmlModuleSymbol(xmlModulePtr module,const char * name,void ** symbol)95 xmlModuleSymbol(xmlModulePtr module, const char *name, void **symbol)
96 {
97     int rc = -1;
98 
99     if ((NULL == module) || (symbol == NULL) || (name == NULL))
100         return rc;
101 
102     rc = xmlModulePlatformSymbol(module->handle, name, symbol);
103 
104     if (rc == -1)
105         return rc;
106 
107     return rc;
108 }
109 
110 /**
111  * xmlModuleClose:
112  * @module: the module handle
113  *
114  * The close operations unload the associated module and free the
115  * data associated to the module.
116  *
117  * Returns 0 in case of success, -1 in case of argument error and -2
118  *         if the module could not be closed/unloaded.
119  */
120 int
xmlModuleClose(xmlModulePtr module)121 xmlModuleClose(xmlModulePtr module)
122 {
123     int rc;
124 
125     if (NULL == module)
126         return -1;
127 
128     rc = xmlModulePlatformClose(module->handle);
129 
130     if (rc != 0)
131         return -2;
132 
133     rc = xmlModuleFree(module);
134     return (rc);
135 }
136 
137 /**
138  * xmlModuleFree:
139  * @module: the module handle
140  *
141  * The free operations free the data associated to the module
142  * but does not unload the associated shared library which may still
143  * be in use.
144  *
145  * Returns 0 in case of success, -1 in case of argument error
146  */
147 int
xmlModuleFree(xmlModulePtr module)148 xmlModuleFree(xmlModulePtr module)
149 {
150     if (NULL == module)
151         return -1;
152 
153     xmlFree(module->name);
154     xmlFree(module);
155 
156     return (0);
157 }
158 
159 #if defined(HAVE_DLOPEN) && !defined(_WIN32)
160 #include <dlfcn.h>
161 
162 #ifndef RTLD_GLOBAL            /* For Tru64 UNIX 4.0 */
163 #define RTLD_GLOBAL 0
164 #endif
165 
166 /**
167  * xmlModulePlatformOpen:
168  * @name: path to the module
169  *
170  * returns a handle on success, and zero on error.
171  */
172 
173 static void *
xmlModulePlatformOpen(const char * name)174 xmlModulePlatformOpen(const char *name)
175 {
176     return dlopen(name, RTLD_GLOBAL | RTLD_NOW);
177 }
178 
179 /*
180  * xmlModulePlatformClose:
181  * @handle: handle to the module
182  *
183  * returns 0 on success, and non-zero on error.
184  */
185 
186 static int
xmlModulePlatformClose(void * handle)187 xmlModulePlatformClose(void *handle)
188 {
189     return dlclose(handle);
190 }
191 
192 /*
193  * xmlModulePlatformSymbol:
194  * http://www.opengroup.org/onlinepubs/009695399/functions/dlsym.html
195  * returns 0 on success and the loaded symbol in result, and -1 on error.
196  */
197 
198 static int
xmlModulePlatformSymbol(void * handle,const char * name,void ** symbol)199 xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
200 {
201     *symbol = dlsym(handle, name);
202     if (dlerror() != NULL) {
203 	return -1;
204     }
205     return 0;
206 }
207 
208 #else /* ! HAVE_DLOPEN */
209 
210 #ifdef HAVE_SHLLOAD             /* HAVE_SHLLOAD */
211 #include <dl.h>
212 /*
213  * xmlModulePlatformOpen:
214  * returns a handle on success, and zero on error.
215  */
216 
217 static void *
xmlModulePlatformOpen(const char * name)218 xmlModulePlatformOpen(const char *name)
219 {
220     return shl_load(name, BIND_IMMEDIATE, 0L);
221 }
222 
223 /*
224  * xmlModulePlatformClose:
225  * returns 0 on success, and non-zero on error.
226  */
227 
228 static int
xmlModulePlatformClose(void * handle)229 xmlModulePlatformClose(void *handle)
230 {
231     return shl_unload(handle);
232 }
233 
234 /*
235  * xmlModulePlatformSymbol:
236  * http://docs.hp.com/en/B2355-90683/shl_load.3X.html
237  * returns 0 on success and the loaded symbol in result, and -1 on error.
238  */
239 
240 static int
xmlModulePlatformSymbol(void * handle,const char * name,void ** symbol)241 xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
242 {
243     int rc;
244 
245     errno = 0;
246     rc = shl_findsym(&handle, name, TYPE_UNDEFINED, symbol);
247     return rc;
248 }
249 
250 #endif /* HAVE_SHLLOAD */
251 #endif /* ! HAVE_DLOPEN */
252 
253 #if defined(_WIN32)
254 
255 #define WIN32_LEAN_AND_MEAN
256 #include <windows.h>
257 
258 /*
259  * xmlModulePlatformOpen:
260  * returns a handle on success, and zero on error.
261  */
262 
263 static void *
xmlModulePlatformOpen(const char * name)264 xmlModulePlatformOpen(const char *name)
265 {
266     return LoadLibraryA(name);
267 }
268 
269 /*
270  * xmlModulePlatformClose:
271  * returns 0 on success, and non-zero on error.
272  */
273 
274 static int
xmlModulePlatformClose(void * handle)275 xmlModulePlatformClose(void *handle)
276 {
277     int rc;
278 
279     rc = FreeLibrary(handle);
280     return (0 == rc);
281 }
282 
283 /*
284  * xmlModulePlatformSymbol:
285  * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/getprocaddress.asp
286  * returns 0 on success and the loaded symbol in result, and -1 on error.
287  */
288 
289 static int
xmlModulePlatformSymbol(void * handle,const char * name,void ** symbol)290 xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
291 {
292 XML_IGNORE_FPTR_CAST_WARNINGS
293     *symbol = GetProcAddress(handle, name);
294     return (NULL == *symbol) ? -1 : 0;
295 XML_POP_WARNINGS
296 }
297 
298 #endif /* _WIN32 */
299 
300 #endif /* LIBXML_MODULES_ENABLED */
301