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>