Annotation of embedaddon/libxml2/xmlmodule.c, revision 1.1.1.2
1.1 misho 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: * joelwreed@comcast.net
7: *
8: * http://www.fortran-2000.com/ArnaudRecipes/sharedlib.html
9: */
10:
11: #define IN_LIBXML
12: #include "libxml.h"
13:
14: #include <string.h>
15: #include <libxml/xmlmemory.h>
16: #include <libxml/xmlerror.h>
17: #include <libxml/xmlmodule.h>
18: #include <libxml/globals.h>
19:
20: #ifdef LIBXML_MODULES_ENABLED
21:
22: struct _xmlModule {
23: unsigned char *name;
24: void *handle;
25: };
26:
27: static void *xmlModulePlatformOpen(const char *name);
28: static int xmlModulePlatformClose(void *handle);
29: static int xmlModulePlatformSymbol(void *handle, const char *name, void **result);
30:
31: /************************************************************************
32: * *
1.1.1.2 ! misho 33: * module memory error handler *
1.1 misho 34: * *
35: ************************************************************************/
36:
37: /**
38: * xmlModuleErrMemory:
39: * @extra: extra information
40: *
41: * Handle an out of memory condition
42: */
43: static void
44: xmlModuleErrMemory(xmlModulePtr module, const char *extra)
45: {
46: const char *name = NULL;
47:
48: if (module != NULL) {
49: name = (const char *) module->name;
50: }
51:
52: __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
53: XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
54: name, NULL, 0, 0,
55: "Memory allocation failed : %s\n", extra);
56: }
57:
58: /**
59: * xmlModuleOpen:
60: * @name: the module name
61: * @options: a set of xmlModuleOption
62: *
63: * Opens a module/shared library given its name or path
1.1.1.2 ! misho 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 * .
1.1 misho 68: * TODO: options are not yet implemented.
69: *
70: * Returns a handle for the module or NULL in case of error
71: */
72: xmlModulePtr
73: xmlModuleOpen(const char *name, int options ATTRIBUTE_UNUSED)
74: {
75: xmlModulePtr module;
76:
77: module = (xmlModulePtr) xmlMalloc(sizeof(xmlModule));
78: if (module == NULL) {
79: xmlModuleErrMemory(NULL, "creating module");
80: return (NULL);
81: }
82:
83: memset(module, 0, sizeof(xmlModule));
84:
85: module->handle = xmlModulePlatformOpen(name);
86:
87: if (module->handle == NULL) {
88: xmlFree(module);
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);
92: return(NULL);
93: }
94:
95: module->name = xmlStrdup((const xmlChar *) name);
96: return (module);
97: }
98:
99: /**
100: * xmlModuleSymbol:
101: * @module: the module
102: * @name: the name of the symbol
103: * @symbol: the resulting symbol address
104: *
105: * Lookup for a symbol address in the given module
1.1.1.2 ! misho 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 * .
1.1 misho 110: *
111: * Returns 0 if the symbol was found, or -1 in case of error
112: */
113: int
114: xmlModuleSymbol(xmlModulePtr module, const char *name, void **symbol)
115: {
116: int rc = -1;
1.1.1.2 ! misho 117:
1.1 misho 118: if ((NULL == module) || (symbol == 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");
122: return rc;
123: }
124:
125: rc = xmlModulePlatformSymbol(module->handle, name, symbol);
126:
127: if (rc == -1) {
128: __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
129: XML_MODULE_OPEN, XML_ERR_FATAL, NULL, 0, 0,
130: name, NULL, 0, 0,
131: "failed to find symbol: %s\n",
132: (name == NULL ? "NULL" : name));
133: return rc;
134: }
135:
136: return rc;
137: }
138:
139: /**
140: * xmlModuleClose:
141: * @module: the module handle
142: *
143: * The close operations unload the associated module and free the
144: * data associated to the module.
145: *
146: * Returns 0 in case of success, -1 in case of argument error and -2
147: * if the module could not be closed/unloaded.
148: */
149: int
150: xmlModuleClose(xmlModulePtr module)
151: {
152: int rc;
153:
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");
158: return -1;
159: }
160:
161: rc = xmlModulePlatformClose(module->handle);
162:
163: if (rc != 0) {
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);
168: return -2;
169: }
170:
171: rc = xmlModuleFree(module);
172: return (rc);
173: }
174:
175: /**
176: * xmlModuleFree:
177: * @module: the module handle
178: *
179: * The free operations free the data associated to the module
180: * but does not unload the associated shared library which may still
181: * be in use.
182: *
183: * Returns 0 in case of success, -1 in case of argument error
184: */
185: int
186: xmlModuleFree(xmlModulePtr module)
187: {
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");
192: return -1;
193: }
194:
195: xmlFree(module->name);
196: xmlFree(module);
197:
198: return (0);
199: }
200:
201: #if defined(HAVE_DLOPEN) && !defined(_WIN32)
202: #ifdef HAVE_DLFCN_H
203: #include <dlfcn.h>
204: #endif
205:
206: #ifndef RTLD_GLOBAL /* For Tru64 UNIX 4.0 */
207: #define RTLD_GLOBAL 0
208: #endif
209:
210: /**
211: * xmlModulePlatformOpen:
212: * @name: path to the module
213: *
214: * returns a handle on success, and zero on error.
215: */
216:
217: static void *
218: xmlModulePlatformOpen(const char *name)
219: {
220: return dlopen(name, RTLD_GLOBAL | RTLD_NOW);
221: }
222:
223: /*
224: * xmlModulePlatformClose:
225: * @handle: handle to the module
226: *
227: * returns 0 on success, and non-zero on error.
228: */
229:
230: static int
231: xmlModulePlatformClose(void *handle)
232: {
233: return dlclose(handle);
234: }
235:
236: /*
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.
240: */
241:
242: static int
243: xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
244: {
245: *symbol = dlsym(handle, name);
246: if (dlerror() != NULL) {
247: return -1;
248: }
249: return 0;
250: }
251:
252: #else /* ! HAVE_DLOPEN */
253:
254: #ifdef HAVE_SHLLOAD /* HAVE_SHLLOAD */
255: #ifdef HAVE_DL_H
256: #include <dl.h>
257: #endif
258: /*
259: * xmlModulePlatformOpen:
260: * returns a handle on success, and zero on error.
261: */
262:
263: static void *
264: xmlModulePlatformOpen(const char *name)
265: {
266: return shl_load(name, BIND_IMMEDIATE, 0L);
267: }
268:
269: /*
270: * xmlModulePlatformClose:
271: * returns 0 on success, and non-zero on error.
272: */
273:
274: static int
275: xmlModulePlatformClose(void *handle)
276: {
277: return shl_unload(handle);
278: }
279:
280: /*
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.
284: */
285:
286: static int
287: xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
288: {
289: int rc;
290:
291: errno = 0;
292: rc = shl_findsym(&handle, name, TYPE_UNDEFINED, symbol);
293: return rc;
294: }
295:
296: #endif /* HAVE_SHLLOAD */
297: #endif /* ! HAVE_DLOPEN */
298:
299: #ifdef _WIN32
300:
301: #include <windows.h>
302:
303: /*
304: * xmlModulePlatformOpen:
305: * returns a handle on success, and zero on error.
306: */
307:
308: static void *
309: xmlModulePlatformOpen(const char *name)
310: {
1.1.1.2 ! misho 311: return LoadLibraryA(name);
1.1 misho 312: }
313:
314: /*
315: * xmlModulePlatformClose:
316: * returns 0 on success, and non-zero on error.
317: */
318:
319: static int
320: xmlModulePlatformClose(void *handle)
321: {
322: int rc;
323:
324: rc = FreeLibrary(handle);
325: return (0 == rc);
326: }
327:
328: /*
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.
332: */
333:
334: static int
335: xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
336: {
1.1.1.2 ! misho 337: #ifdef _WIN32_WCE
! 338: /*
! 339: * GetProcAddressA seems only available on WinCE
! 340: */
! 341: *symbol = GetProcAddressA(handle, name);
! 342: #else
1.1 misho 343: *symbol = GetProcAddress(handle, name);
1.1.1.2 ! misho 344: #endif
1.1 misho 345: return (NULL == *symbol) ? -1 : 0;
346: }
347:
348: #endif /* _WIN32 */
349:
350: #ifdef HAVE_BEOS
351:
352: #include <kernel/image.h>
353:
354: /*
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.
358: */
359:
360: static void *
361: xmlModulePlatformOpen(const char *name)
362: {
363: return (void *) load_add_on(name);
364: }
365:
366: /*
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.
370: */
371:
372: static int
373: xmlModulePlatformClose(void *handle)
374: {
375: status_t rc;
376:
377: rc = unload_add_on((image_id) handle);
378:
379: if (rc == B_OK)
380: return 0;
381: else
382: return -1;
383: }
384:
385: /*
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.
389: */
390:
391: static int
392: xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
393: {
394: status_t rc;
395:
396: rc = get_image_symbol((image_id) handle, name, B_SYMBOL_TYPE_ANY, symbol);
397:
398: return (rc == B_OK) ? 0 : -1;
399: }
400:
401: #endif /* HAVE_BEOS */
402:
403: #ifdef HAVE_OS2
404:
405: #include <os2.h>
406:
407: /*
408: * xmlModulePlatformOpen:
409: * os2 api info: http://www.edm2.com/os2api/Dos/DosLoadModule.html
410: * returns a handle on success, and zero on error.
411: */
412:
413: static void *
414: xmlModulePlatformOpen(const char *name)
415: {
416: char errbuf[256];
417: void *handle;
418: int rc;
419:
420: rc = DosLoadModule(errbuf, sizeof(errbuf) - 1, name, &handle);
421:
422: if (rc)
423: return 0;
424: else
425: return (handle);
426: }
427:
428: /*
429: * xmlModulePlatformClose:
430: * os2 api info: http://www.edm2.com/os2api/Dos/DosFreeModule.html
431: * returns 0 on success, and non-zero on error.
432: */
433:
434: static int
435: xmlModulePlatformClose(void *handle)
436: {
437: return DosFreeModule(handle);
438: }
439:
440: /*
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.
444: */
445:
446: static int
447: xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
448: {
449: int rc;
450:
451: rc = DosQueryProcAddr(handle, 0, name, symbol);
452:
453: return (rc == NO_ERROR) ? 0 : -1;
454: }
455:
456: #endif /* HAVE_OS2 */
457:
458: #define bottom_xmlmodule
459: #include "elfgcchack.h"
460: #endif /* LIBXML_MODULES_ENABLED */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>