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>