Annotation of embedaddon/libxml2/xmlmodule.c, revision 1.1.1.1
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: * *
33: * module memory error handler *
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
64: * TODO: options are not yet implemented.
65: *
66: * Returns a handle for the module or NULL in case of error
67: */
68: xmlModulePtr
69: xmlModuleOpen(const char *name, int options ATTRIBUTE_UNUSED)
70: {
71: xmlModulePtr module;
72:
73: module = (xmlModulePtr) xmlMalloc(sizeof(xmlModule));
74: if (module == NULL) {
75: xmlModuleErrMemory(NULL, "creating module");
76: return (NULL);
77: }
78:
79: memset(module, 0, sizeof(xmlModule));
80:
81: module->handle = xmlModulePlatformOpen(name);
82:
83: if (module->handle == NULL) {
84: xmlFree(module);
85: __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
86: XML_MODULE_OPEN, XML_ERR_FATAL, NULL, 0, 0,
87: name, NULL, 0, 0, "failed to open %s\n", name);
88: return(NULL);
89: }
90:
91: module->name = xmlStrdup((const xmlChar *) name);
92: return (module);
93: }
94:
95: /**
96: * xmlModuleSymbol:
97: * @module: the module
98: * @name: the name of the symbol
99: * @symbol: the resulting symbol address
100: *
101: * Lookup for a symbol address in the given module
102: *
103: * Returns 0 if the symbol was found, or -1 in case of error
104: */
105: int
106: xmlModuleSymbol(xmlModulePtr module, const char *name, void **symbol)
107: {
108: int rc = -1;
109:
110: if ((NULL == module) || (symbol == NULL)) {
111: __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
112: XML_MODULE_OPEN, XML_ERR_FATAL, NULL, 0, 0,
113: NULL, NULL, 0, 0, "null parameter\n");
114: return rc;
115: }
116:
117: rc = xmlModulePlatformSymbol(module->handle, name, symbol);
118:
119: if (rc == -1) {
120: __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
121: XML_MODULE_OPEN, XML_ERR_FATAL, NULL, 0, 0,
122: name, NULL, 0, 0,
123: "failed to find symbol: %s\n",
124: (name == NULL ? "NULL" : name));
125: return rc;
126: }
127:
128: return rc;
129: }
130:
131: /**
132: * xmlModuleClose:
133: * @module: the module handle
134: *
135: * The close operations unload the associated module and free the
136: * data associated to the module.
137: *
138: * Returns 0 in case of success, -1 in case of argument error and -2
139: * if the module could not be closed/unloaded.
140: */
141: int
142: xmlModuleClose(xmlModulePtr module)
143: {
144: int rc;
145:
146: if (NULL == module) {
147: __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
148: XML_MODULE_CLOSE, XML_ERR_FATAL, NULL, 0, 0,
149: NULL, NULL, 0, 0, "null module pointer\n");
150: return -1;
151: }
152:
153: rc = xmlModulePlatformClose(module->handle);
154:
155: if (rc != 0) {
156: __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
157: XML_MODULE_CLOSE, XML_ERR_FATAL, NULL, 0, 0,
158: (const char *) module->name, NULL, 0, 0,
159: "failed to close: %s\n", module->name);
160: return -2;
161: }
162:
163: rc = xmlModuleFree(module);
164: return (rc);
165: }
166:
167: /**
168: * xmlModuleFree:
169: * @module: the module handle
170: *
171: * The free operations free the data associated to the module
172: * but does not unload the associated shared library which may still
173: * be in use.
174: *
175: * Returns 0 in case of success, -1 in case of argument error
176: */
177: int
178: xmlModuleFree(xmlModulePtr module)
179: {
180: if (NULL == module) {
181: __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
182: XML_MODULE_CLOSE, XML_ERR_FATAL, NULL, 0, NULL,
183: NULL, NULL, 0, 0, "null module pointer\n");
184: return -1;
185: }
186:
187: xmlFree(module->name);
188: xmlFree(module);
189:
190: return (0);
191: }
192:
193: #if defined(HAVE_DLOPEN) && !defined(_WIN32)
194: #ifdef HAVE_DLFCN_H
195: #include <dlfcn.h>
196: #endif
197:
198: #ifndef RTLD_GLOBAL /* For Tru64 UNIX 4.0 */
199: #define RTLD_GLOBAL 0
200: #endif
201:
202: /**
203: * xmlModulePlatformOpen:
204: * @name: path to the module
205: *
206: * returns a handle on success, and zero on error.
207: */
208:
209: static void *
210: xmlModulePlatformOpen(const char *name)
211: {
212: return dlopen(name, RTLD_GLOBAL | RTLD_NOW);
213: }
214:
215: /*
216: * xmlModulePlatformClose:
217: * @handle: handle to the module
218: *
219: * returns 0 on success, and non-zero on error.
220: */
221:
222: static int
223: xmlModulePlatformClose(void *handle)
224: {
225: return dlclose(handle);
226: }
227:
228: /*
229: * xmlModulePlatformSymbol:
230: * http://www.opengroup.org/onlinepubs/009695399/functions/dlsym.html
231: * returns 0 on success and the loaded symbol in result, and -1 on error.
232: */
233:
234: static int
235: xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
236: {
237: *symbol = dlsym(handle, name);
238: if (dlerror() != NULL) {
239: return -1;
240: }
241: return 0;
242: }
243:
244: #else /* ! HAVE_DLOPEN */
245:
246: #ifdef HAVE_SHLLOAD /* HAVE_SHLLOAD */
247: #ifdef HAVE_DL_H
248: #include <dl.h>
249: #endif
250: /*
251: * xmlModulePlatformOpen:
252: * returns a handle on success, and zero on error.
253: */
254:
255: static void *
256: xmlModulePlatformOpen(const char *name)
257: {
258: return shl_load(name, BIND_IMMEDIATE, 0L);
259: }
260:
261: /*
262: * xmlModulePlatformClose:
263: * returns 0 on success, and non-zero on error.
264: */
265:
266: static int
267: xmlModulePlatformClose(void *handle)
268: {
269: return shl_unload(handle);
270: }
271:
272: /*
273: * xmlModulePlatformSymbol:
274: * http://docs.hp.com/en/B2355-90683/shl_load.3X.html
275: * returns 0 on success and the loaded symbol in result, and -1 on error.
276: */
277:
278: static int
279: xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
280: {
281: int rc;
282:
283: errno = 0;
284: rc = shl_findsym(&handle, name, TYPE_UNDEFINED, symbol);
285: return rc;
286: }
287:
288: #endif /* HAVE_SHLLOAD */
289: #endif /* ! HAVE_DLOPEN */
290:
291: #ifdef _WIN32
292:
293: #include <windows.h>
294:
295: /*
296: * xmlModulePlatformOpen:
297: * returns a handle on success, and zero on error.
298: */
299:
300: static void *
301: xmlModulePlatformOpen(const char *name)
302: {
303: return LoadLibrary(name);
304: }
305:
306: /*
307: * xmlModulePlatformClose:
308: * returns 0 on success, and non-zero on error.
309: */
310:
311: static int
312: xmlModulePlatformClose(void *handle)
313: {
314: int rc;
315:
316: rc = FreeLibrary(handle);
317: return (0 == rc);
318: }
319:
320: /*
321: * xmlModulePlatformSymbol:
322: * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/getprocaddress.asp
323: * returns 0 on success and the loaded symbol in result, and -1 on error.
324: */
325:
326: static int
327: xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
328: {
329: *symbol = GetProcAddress(handle, name);
330: return (NULL == *symbol) ? -1 : 0;
331: }
332:
333: #endif /* _WIN32 */
334:
335: #ifdef HAVE_BEOS
336:
337: #include <kernel/image.h>
338:
339: /*
340: * xmlModulePlatformOpen:
341: * beos api info: http://www.beunited.org/bebook/The%20Kernel%20Kit/Images.html
342: * returns a handle on success, and zero on error.
343: */
344:
345: static void *
346: xmlModulePlatformOpen(const char *name)
347: {
348: return (void *) load_add_on(name);
349: }
350:
351: /*
352: * xmlModulePlatformClose:
353: * beos api info: http://www.beunited.org/bebook/The%20Kernel%20Kit/Images.html
354: * returns 0 on success, and non-zero on error.
355: */
356:
357: static int
358: xmlModulePlatformClose(void *handle)
359: {
360: status_t rc;
361:
362: rc = unload_add_on((image_id) handle);
363:
364: if (rc == B_OK)
365: return 0;
366: else
367: return -1;
368: }
369:
370: /*
371: * xmlModulePlatformSymbol:
372: * beos api info: http://www.beunited.org/bebook/The%20Kernel%20Kit/Images.html
373: * returns 0 on success and the loaded symbol in result, and -1 on error.
374: */
375:
376: static int
377: xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
378: {
379: status_t rc;
380:
381: rc = get_image_symbol((image_id) handle, name, B_SYMBOL_TYPE_ANY, symbol);
382:
383: return (rc == B_OK) ? 0 : -1;
384: }
385:
386: #endif /* HAVE_BEOS */
387:
388: #ifdef HAVE_OS2
389:
390: #include <os2.h>
391:
392: /*
393: * xmlModulePlatformOpen:
394: * os2 api info: http://www.edm2.com/os2api/Dos/DosLoadModule.html
395: * returns a handle on success, and zero on error.
396: */
397:
398: static void *
399: xmlModulePlatformOpen(const char *name)
400: {
401: char errbuf[256];
402: void *handle;
403: int rc;
404:
405: rc = DosLoadModule(errbuf, sizeof(errbuf) - 1, name, &handle);
406:
407: if (rc)
408: return 0;
409: else
410: return (handle);
411: }
412:
413: /*
414: * xmlModulePlatformClose:
415: * os2 api info: http://www.edm2.com/os2api/Dos/DosFreeModule.html
416: * returns 0 on success, and non-zero on error.
417: */
418:
419: static int
420: xmlModulePlatformClose(void *handle)
421: {
422: return DosFreeModule(handle);
423: }
424:
425: /*
426: * xmlModulePlatformSymbol:
427: * os2 api info: http://www.edm2.com/os2api/Dos/DosQueryProcAddr.html
428: * returns 0 on success and the loaded symbol in result, and -1 on error.
429: */
430:
431: static int
432: xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
433: {
434: int rc;
435:
436: rc = DosQueryProcAddr(handle, 0, name, symbol);
437:
438: return (rc == NO_ERROR) ? 0 : -1;
439: }
440:
441: #endif /* HAVE_OS2 */
442:
443: #define bottom_xmlmodule
444: #include "elfgcchack.h"
445: #endif /* LIBXML_MODULES_ENABLED */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>