File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libxml2 / xmlmodule.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 19:53:28 2014 UTC (9 years, 11 months ago) by misho
Branches: libxml2, MAIN
CVS tags: v2_9_1p0, v2_9_1, HEAD
libxml2 2.9.1

    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:  * 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 * .
   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
  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 * .
  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;
  117: 
  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: {
  311:     return LoadLibraryA(name);
  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: {
  337: #ifdef _WIN32_WCE
  338:     /*
  339:      * GetProcAddressA seems only available on WinCE
  340:      */
  341:     *symbol = GetProcAddressA(handle, name);
  342: #else
  343:     *symbol = GetProcAddress(handle, name);
  344: #endif
  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>