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>