File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libxml2 / xmlmodule.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 23:37:58 2012 UTC (12 years, 4 months ago) by misho
Branches: libxml2, MAIN
CVS tags: v2_8_0p0, v2_8_0, v2_7_8, HEAD
libxml2

    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>