2 * xmlmodule.c : basic API for dynamic module loading added 2.6.17
4 * See Copyright for the status of this software.
6 * joelwreed@comcast.net
8 * http://www.fortran-2000.com/ArnaudRecipes/sharedlib.html
11 /* In order RTLD_GLOBAL and RTLD_NOW to be defined on zOS */
13 #define _UNIX03_SOURCE
20 #include <libxml/xmlmemory.h>
21 #include <libxml/xmlerror.h>
22 #include <libxml/xmlmodule.h>
23 #include <libxml/globals.h>
25 #ifdef LIBXML_MODULES_ENABLED
32 static void *xmlModulePlatformOpen(const char *name);
33 static int xmlModulePlatformClose(void *handle);
34 static int xmlModulePlatformSymbol(void *handle, const char *name, void **result);
36 /************************************************************************
38 * module memory error handler *
40 ************************************************************************/
44 * @extra: extra information
46 * Handle an out of memory condition
49 xmlModuleErrMemory(xmlModulePtr module, const char *extra)
51 const char *name = NULL;
54 name = (const char *) module->name;
57 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
58 XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
60 "Memory allocation failed : %s\n", extra);
65 * @name: the module name
66 * @options: a set of xmlModuleOption
68 * Opens a module/shared library given its name or path
69 * NOTE: that due to portability issues, behaviour can only be
70 * guaranteed with @name using ASCII. We canot guarantee that
71 * an UTF-8 string would work, which is why name is a const char *
72 * and not a const xmlChar * .
73 * TODO: options are not yet implemented.
75 * Returns a handle for the module or NULL in case of error
78 xmlModuleOpen(const char *name, int options ATTRIBUTE_UNUSED)
82 module = (xmlModulePtr) xmlMalloc(sizeof(xmlModule));
84 xmlModuleErrMemory(NULL, "creating module");
88 memset(module, 0, sizeof(xmlModule));
90 module->handle = xmlModulePlatformOpen(name);
92 if (module->handle == NULL) {
94 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
95 XML_MODULE_OPEN, XML_ERR_FATAL, NULL, 0, 0,
96 name, NULL, 0, 0, "failed to open %s\n", name);
100 module->name = xmlStrdup((const xmlChar *) name);
106 * @module: the module
107 * @name: the name of the symbol
108 * @symbol: the resulting symbol address
110 * Lookup for a symbol address in the given module
111 * NOTE: that due to portability issues, behaviour can only be
112 * guaranteed with @name using ASCII. We canot guarantee that
113 * an UTF-8 string would work, which is why name is a const char *
114 * and not a const xmlChar * .
116 * Returns 0 if the symbol was found, or -1 in case of error
119 xmlModuleSymbol(xmlModulePtr module, const char *name, void **symbol)
123 if ((NULL == module) || (symbol == NULL) || (name == NULL)) {
124 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
125 XML_MODULE_OPEN, XML_ERR_FATAL, NULL, 0, 0,
126 NULL, NULL, 0, 0, "null parameter\n");
130 rc = xmlModulePlatformSymbol(module->handle, name, symbol);
133 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
134 XML_MODULE_OPEN, XML_ERR_FATAL, NULL, 0, 0,
136 "failed to find symbol: %s\n",
137 (name == NULL ? "NULL" : name));
146 * @module: the module handle
148 * The close operations unload the associated module and free the
149 * data associated to the module.
151 * Returns 0 in case of success, -1 in case of argument error and -2
152 * if the module could not be closed/unloaded.
155 xmlModuleClose(xmlModulePtr module)
159 if (NULL == module) {
160 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
161 XML_MODULE_CLOSE, XML_ERR_FATAL, NULL, 0, 0,
162 NULL, NULL, 0, 0, "null module pointer\n");
166 rc = xmlModulePlatformClose(module->handle);
169 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
170 XML_MODULE_CLOSE, XML_ERR_FATAL, NULL, 0, 0,
171 (const char *) module->name, NULL, 0, 0,
172 "failed to close: %s\n", module->name);
176 rc = xmlModuleFree(module);
182 * @module: the module handle
184 * The free operations free the data associated to the module
185 * but does not unload the associated shared library which may still
188 * Returns 0 in case of success, -1 in case of argument error
191 xmlModuleFree(xmlModulePtr module)
193 if (NULL == module) {
194 __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
195 XML_MODULE_CLOSE, XML_ERR_FATAL, NULL, 0, NULL,
196 NULL, NULL, 0, 0, "null module pointer\n");
200 xmlFree(module->name);
206 #if defined(HAVE_DLOPEN) && !defined(_WIN32)
211 #ifndef RTLD_GLOBAL /* For Tru64 UNIX 4.0 */
212 #define RTLD_GLOBAL 0
216 * xmlModulePlatformOpen:
217 * @name: path to the module
219 * returns a handle on success, and zero on error.
223 xmlModulePlatformOpen(const char *name)
225 return dlopen(name, RTLD_GLOBAL | RTLD_NOW);
229 * xmlModulePlatformClose:
230 * @handle: handle to the module
232 * returns 0 on success, and non-zero on error.
236 xmlModulePlatformClose(void *handle)
238 return dlclose(handle);
242 * xmlModulePlatformSymbol:
243 * http://www.opengroup.org/onlinepubs/009695399/functions/dlsym.html
244 * returns 0 on success and the loaded symbol in result, and -1 on error.
248 xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
250 *symbol = dlsym(handle, name);
251 if (dlerror() != NULL) {
257 #else /* ! HAVE_DLOPEN */
259 #ifdef HAVE_SHLLOAD /* HAVE_SHLLOAD */
264 * xmlModulePlatformOpen:
265 * returns a handle on success, and zero on error.
269 xmlModulePlatformOpen(const char *name)
271 return shl_load(name, BIND_IMMEDIATE, 0L);
275 * xmlModulePlatformClose:
276 * returns 0 on success, and non-zero on error.
280 xmlModulePlatformClose(void *handle)
282 return shl_unload(handle);
286 * xmlModulePlatformSymbol:
287 * http://docs.hp.com/en/B2355-90683/shl_load.3X.html
288 * returns 0 on success and the loaded symbol in result, and -1 on error.
292 xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
297 rc = shl_findsym(&handle, name, TYPE_UNDEFINED, symbol);
301 #endif /* HAVE_SHLLOAD */
302 #endif /* ! HAVE_DLOPEN */
304 #if defined(_WIN32) && !defined(__CYGWIN__)
306 #define WIN32_LEAN_AND_MEAN
310 * xmlModulePlatformOpen:
311 * returns a handle on success, and zero on error.
315 xmlModulePlatformOpen(const char *name)
317 return LoadLibraryA(name);
321 * xmlModulePlatformClose:
322 * returns 0 on success, and non-zero on error.
326 xmlModulePlatformClose(void *handle)
330 rc = FreeLibrary(handle);
335 * xmlModulePlatformSymbol:
336 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/getprocaddress.asp
337 * returns 0 on success and the loaded symbol in result, and -1 on error.
341 xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
345 * GetProcAddressA seems only available on WinCE
347 *symbol = GetProcAddressA(handle, name);
349 *symbol = GetProcAddress(handle, name);
351 return (NULL == *symbol) ? -1 : 0;
358 #include <kernel/image.h>
361 * xmlModulePlatformOpen:
362 * beos api info: http://www.beunited.org/bebook/The%20Kernel%20Kit/Images.html
363 * returns a handle on success, and zero on error.
367 xmlModulePlatformOpen(const char *name)
369 return (void *) load_add_on(name);
373 * xmlModulePlatformClose:
374 * beos api info: http://www.beunited.org/bebook/The%20Kernel%20Kit/Images.html
375 * returns 0 on success, and non-zero on error.
379 xmlModulePlatformClose(void *handle)
383 rc = unload_add_on((image_id) handle);
392 * xmlModulePlatformSymbol:
393 * beos api info: http://www.beunited.org/bebook/The%20Kernel%20Kit/Images.html
394 * returns 0 on success and the loaded symbol in result, and -1 on error.
398 xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
402 rc = get_image_symbol((image_id) handle, name, B_SYMBOL_TYPE_ANY, symbol);
404 return (rc == B_OK) ? 0 : -1;
407 #endif /* HAVE_BEOS */
414 * xmlModulePlatformOpen:
415 * os2 api info: http://www.edm2.com/os2api/Dos/DosLoadModule.html
416 * returns a handle on success, and zero on error.
420 xmlModulePlatformOpen(const char *name)
426 rc = DosLoadModule(errbuf, sizeof(errbuf) - 1, name, &handle);
435 * xmlModulePlatformClose:
436 * os2 api info: http://www.edm2.com/os2api/Dos/DosFreeModule.html
437 * returns 0 on success, and non-zero on error.
441 xmlModulePlatformClose(void *handle)
443 return DosFreeModule(handle);
447 * xmlModulePlatformSymbol:
448 * os2 api info: http://www.edm2.com/os2api/Dos/DosQueryProcAddr.html
449 * returns 0 on success and the loaded symbol in result, and -1 on error.
453 xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
457 rc = DosQueryProcAddr(handle, 0, name, symbol);
459 return (rc == NO_ERROR) ? 0 : -1;
462 #endif /* HAVE_OS2 */
464 #define bottom_xmlmodule
465 #include "elfgcchack.h"
466 #endif /* LIBXML_MODULES_ENABLED */