Annotation of embedaddon/libxml2/xmlmodule.c, revision 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>