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
15 #include <libxml/xmlmemory.h>
16 #include <libxml/xmlerror.h>
17 #include <libxml/xmlmodule.h>
18 #include <libxml/globals.h>
20 #ifdef LIBXML_MODULES_ENABLED
27 static void *xmlModulePlatformOpen(const char *name
);
28 static int xmlModulePlatformClose(void *handle
);
29 static int xmlModulePlatformSymbol(void *handle
, const char *name
, void **result
);
31 /************************************************************************
33 * module memory error handler *
35 ************************************************************************/
39 * @extra: extra information
41 * Handle an out of memory condition
44 xmlModuleErrMemory(xmlModulePtr module
, const char *extra
)
46 const char *name
= NULL
;
49 name
= (const char *) module
->name
;
52 __xmlRaiseError(NULL
, NULL
, NULL
, NULL
, NULL
, XML_FROM_MODULE
,
53 XML_ERR_NO_MEMORY
, XML_ERR_FATAL
, NULL
, 0, extra
,
55 "Memory allocation failed : %s\n", extra
);
60 * @name: the module name
61 * @options: a set of xmlModuleOption
63 * Opens a module/shared library given its name or path
64 * NOTE: that due to portability issues, behaviour can only be
65 * guaranteed with @name using ASCII. We canot guarantee that
66 * an UTF-8 string would work, which is why name is a const char *
67 * and not a const xmlChar * .
68 * TODO: options are not yet implemented.
70 * Returns a handle for the module or NULL in case of error
73 xmlModuleOpen(const char *name
, int options ATTRIBUTE_UNUSED
)
77 module
= (xmlModulePtr
) xmlMalloc(sizeof(xmlModule
));
79 xmlModuleErrMemory(NULL
, "creating module");
83 memset(module
, 0, sizeof(xmlModule
));
85 module
->handle
= xmlModulePlatformOpen(name
);
87 if (module
->handle
== NULL
) {
89 __xmlRaiseError(NULL
, NULL
, NULL
, NULL
, NULL
, XML_FROM_MODULE
,
90 XML_MODULE_OPEN
, XML_ERR_FATAL
, NULL
, 0, 0,
91 name
, NULL
, 0, 0, "failed to open %s\n", name
);
95 module
->name
= xmlStrdup((const xmlChar
*) name
);
101 * @module: the module
102 * @name: the name of the symbol
103 * @symbol: the resulting symbol address
105 * Lookup for a symbol address in the given module
106 * NOTE: that due to portability issues, behaviour can only be
107 * guaranteed with @name using ASCII. We canot guarantee that
108 * an UTF-8 string would work, which is why name is a const char *
109 * and not a const xmlChar * .
111 * Returns 0 if the symbol was found, or -1 in case of error
114 xmlModuleSymbol(xmlModulePtr module
, const char *name
, void **symbol
)
118 if ((NULL
== module
) || (symbol
== NULL
) || (name
== NULL
)) {
119 __xmlRaiseError(NULL
, NULL
, NULL
, NULL
, NULL
, XML_FROM_MODULE
,
120 XML_MODULE_OPEN
, XML_ERR_FATAL
, NULL
, 0, 0,
121 NULL
, NULL
, 0, 0, "null parameter\n");
125 rc
= xmlModulePlatformSymbol(module
->handle
, name
, symbol
);
128 __xmlRaiseError(NULL
, NULL
, NULL
, NULL
, NULL
, XML_FROM_MODULE
,
129 XML_MODULE_OPEN
, XML_ERR_FATAL
, NULL
, 0, 0,
131 "failed to find symbol: %s\n",
132 (name
== NULL
? "NULL" : name
));
141 * @module: the module handle
143 * The close operations unload the associated module and free the
144 * data associated to the module.
146 * Returns 0 in case of success, -1 in case of argument error and -2
147 * if the module could not be closed/unloaded.
150 xmlModuleClose(xmlModulePtr module
)
154 if (NULL
== module
) {
155 __xmlRaiseError(NULL
, NULL
, NULL
, NULL
, NULL
, XML_FROM_MODULE
,
156 XML_MODULE_CLOSE
, XML_ERR_FATAL
, NULL
, 0, 0,
157 NULL
, NULL
, 0, 0, "null module pointer\n");
161 rc
= xmlModulePlatformClose(module
->handle
);
164 __xmlRaiseError(NULL
, NULL
, NULL
, NULL
, NULL
, XML_FROM_MODULE
,
165 XML_MODULE_CLOSE
, XML_ERR_FATAL
, NULL
, 0, 0,
166 (const char *) module
->name
, NULL
, 0, 0,
167 "failed to close: %s\n", module
->name
);
171 rc
= xmlModuleFree(module
);
177 * @module: the module handle
179 * The free operations free the data associated to the module
180 * but does not unload the associated shared library which may still
183 * Returns 0 in case of success, -1 in case of argument error
186 xmlModuleFree(xmlModulePtr module
)
188 if (NULL
== module
) {
189 __xmlRaiseError(NULL
, NULL
, NULL
, NULL
, NULL
, XML_FROM_MODULE
,
190 XML_MODULE_CLOSE
, XML_ERR_FATAL
, NULL
, 0, NULL
,
191 NULL
, NULL
, 0, 0, "null module pointer\n");
195 xmlFree(module
->name
);
201 #if defined(HAVE_DLOPEN) && !defined(_WIN32)
206 #ifndef RTLD_GLOBAL /* For Tru64 UNIX 4.0 */
207 #define RTLD_GLOBAL 0
211 * xmlModulePlatformOpen:
212 * @name: path to the module
214 * returns a handle on success, and zero on error.
218 xmlModulePlatformOpen(const char *name
)
220 return dlopen(name
, RTLD_GLOBAL
| RTLD_NOW
);
224 * xmlModulePlatformClose:
225 * @handle: handle to the module
227 * returns 0 on success, and non-zero on error.
231 xmlModulePlatformClose(void *handle
)
233 return dlclose(handle
);
237 * xmlModulePlatformSymbol:
238 * http://www.opengroup.org/onlinepubs/009695399/functions/dlsym.html
239 * returns 0 on success and the loaded symbol in result, and -1 on error.
243 xmlModulePlatformSymbol(void *handle
, const char *name
, void **symbol
)
245 *symbol
= dlsym(handle
, name
);
246 if (dlerror() != NULL
) {
252 #else /* ! HAVE_DLOPEN */
254 #ifdef HAVE_SHLLOAD /* HAVE_SHLLOAD */
259 * xmlModulePlatformOpen:
260 * returns a handle on success, and zero on error.
264 xmlModulePlatformOpen(const char *name
)
266 return shl_load(name
, BIND_IMMEDIATE
, 0L);
270 * xmlModulePlatformClose:
271 * returns 0 on success, and non-zero on error.
275 xmlModulePlatformClose(void *handle
)
277 return shl_unload(handle
);
281 * xmlModulePlatformSymbol:
282 * http://docs.hp.com/en/B2355-90683/shl_load.3X.html
283 * returns 0 on success and the loaded symbol in result, and -1 on error.
287 xmlModulePlatformSymbol(void *handle
, const char *name
, void **symbol
)
292 rc
= shl_findsym(&handle
, name
, TYPE_UNDEFINED
, symbol
);
296 #endif /* HAVE_SHLLOAD */
297 #endif /* ! HAVE_DLOPEN */
304 * xmlModulePlatformOpen:
305 * returns a handle on success, and zero on error.
309 xmlModulePlatformOpen(const char *name
)
311 return LoadLibraryA(name
);
315 * xmlModulePlatformClose:
316 * returns 0 on success, and non-zero on error.
320 xmlModulePlatformClose(void *handle
)
324 rc
= FreeLibrary(handle
);
329 * xmlModulePlatformSymbol:
330 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/getprocaddress.asp
331 * returns 0 on success and the loaded symbol in result, and -1 on error.
335 xmlModulePlatformSymbol(void *handle
, const char *name
, void **symbol
)
339 * GetProcAddressA seems only available on WinCE
341 *symbol
= GetProcAddressA(handle
, name
);
343 *symbol
= GetProcAddress(handle
, name
);
345 return (NULL
== *symbol
) ? -1 : 0;
352 #include <kernel/image.h>
355 * xmlModulePlatformOpen:
356 * beos api info: http://www.beunited.org/bebook/The%20Kernel%20Kit/Images.html
357 * returns a handle on success, and zero on error.
361 xmlModulePlatformOpen(const char *name
)
363 return (void *) load_add_on(name
);
367 * xmlModulePlatformClose:
368 * beos api info: http://www.beunited.org/bebook/The%20Kernel%20Kit/Images.html
369 * returns 0 on success, and non-zero on error.
373 xmlModulePlatformClose(void *handle
)
377 rc
= unload_add_on((image_id
) handle
);
386 * xmlModulePlatformSymbol:
387 * beos api info: http://www.beunited.org/bebook/The%20Kernel%20Kit/Images.html
388 * returns 0 on success and the loaded symbol in result, and -1 on error.
392 xmlModulePlatformSymbol(void *handle
, const char *name
, void **symbol
)
396 rc
= get_image_symbol((image_id
) handle
, name
, B_SYMBOL_TYPE_ANY
, symbol
);
398 return (rc
== B_OK
) ? 0 : -1;
401 #endif /* HAVE_BEOS */
408 * xmlModulePlatformOpen:
409 * os2 api info: http://www.edm2.com/os2api/Dos/DosLoadModule.html
410 * returns a handle on success, and zero on error.
414 xmlModulePlatformOpen(const char *name
)
420 rc
= DosLoadModule(errbuf
, sizeof(errbuf
) - 1, name
, &handle
);
429 * xmlModulePlatformClose:
430 * os2 api info: http://www.edm2.com/os2api/Dos/DosFreeModule.html
431 * returns 0 on success, and non-zero on error.
435 xmlModulePlatformClose(void *handle
)
437 return DosFreeModule(handle
);
441 * xmlModulePlatformSymbol:
442 * os2 api info: http://www.edm2.com/os2api/Dos/DosQueryProcAddr.html
443 * returns 0 on success and the loaded symbol in result, and -1 on error.
447 xmlModulePlatformSymbol(void *handle
, const char *name
, void **symbol
)
451 rc
= DosQueryProcAddr(handle
, 0, name
, symbol
);
453 return (rc
== NO_ERROR
) ? 0 : -1;
456 #endif /* HAVE_OS2 */
458 #define bottom_xmlmodule
459 #include "elfgcchack.h"
460 #endif /* LIBXML_MODULES_ENABLED */