2005-01-04 15:10:22 +00:00
/*
2005-01-04 17:50:14 +00:00
* xmlmodule . c : basic API for dynamic module loading added 2.6 .17
2005-01-04 15:10:22 +00:00
*
* See Copyright for the status of this software .
*
* joelwreed @ comcast . net
2005-01-04 20:18:14 +00:00
*
* http : //www.fortran-2000.com/ArnaudRecipes/sharedlib.html
2005-01-04 15:10:22 +00:00
*/
# define IN_LIBXML
# include "libxml.h"
# include <string.h>
# include <libxml/xmlmemory.h>
# include <libxml/xmlerror.h>
# include <libxml/xmlmodule.h>
# include <libxml/globals.h>
# ifdef LIBXML_MODULES_ENABLED
struct _xmlModule {
2005-01-04 17:50:14 +00:00
unsigned char * name ;
void * handle ;
2005-01-04 15:10:22 +00:00
} ;
2005-01-04 17:50:14 +00:00
static void * xmlModulePlatformOpen ( const char * name ) ;
static int xmlModulePlatformClose ( void * handle ) ;
2005-01-04 20:18:14 +00:00
static int xmlModulePlatformSymbol ( void * handle , const char * name , void * * result ) ;
2005-01-04 15:10:22 +00:00
/************************************************************************
* *
2012-09-11 13:26:36 +08:00
* module memory error handler *
2005-01-04 15:10:22 +00:00
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-01-04 17:50:14 +00:00
2005-01-04 15:10:22 +00:00
/**
* xmlModuleErrMemory :
* @ extra : extra information
*
* Handle an out of memory condition
*/
static void
xmlModuleErrMemory ( xmlModulePtr module , const char * extra )
{
const char * name = NULL ;
2005-01-04 17:50:14 +00:00
2005-01-04 15:10:22 +00:00
if ( module ! = NULL ) {
2005-01-04 17:50:14 +00:00
name = ( const char * ) module - > name ;
2005-01-04 15:10:22 +00:00
}
__xmlRaiseError ( NULL , NULL , NULL , NULL , NULL , XML_FROM_MODULE ,
XML_ERR_NO_MEMORY , XML_ERR_FATAL , NULL , 0 , extra ,
name , NULL , 0 , 0 ,
" Memory allocation failed : %s \n " , extra ) ;
}
2005-01-04 17:50:14 +00:00
/**
* xmlModuleOpen :
* @ name : the module name
2005-01-04 21:50:05 +00:00
* @ options : a set of xmlModuleOption
2005-01-04 17:50:14 +00:00
*
* Opens a module / shared library given its name or path
2012-08-13 17:39:06 +08:00
* NOTE : that due to portability issues , behaviour can only be
* guaranteed with @ name using ASCII . We canot guarantee that
* an UTF - 8 string would work , which is why name is a const char *
* and not a const xmlChar * .
2005-01-04 21:50:05 +00:00
* TODO : options are not yet implemented .
2005-01-04 17:50:14 +00:00
*
* Returns a handle for the module or NULL in case of error
*/
xmlModulePtr
2005-01-04 21:50:05 +00:00
xmlModuleOpen ( const char * name , int options ATTRIBUTE_UNUSED )
2005-01-04 15:10:22 +00:00
{
2005-01-04 17:50:14 +00:00
xmlModulePtr module ;
2005-01-04 15:10:22 +00:00
2005-01-04 17:50:14 +00:00
module = ( xmlModulePtr ) xmlMalloc ( sizeof ( xmlModule ) ) ;
if ( module = = NULL ) {
xmlModuleErrMemory ( NULL , " creating module " ) ;
return ( NULL ) ;
}
2005-01-04 15:10:22 +00:00
2005-01-04 17:50:14 +00:00
memset ( module , 0 , sizeof ( xmlModule ) ) ;
2005-01-04 15:10:22 +00:00
2005-01-04 17:50:14 +00:00
module - > handle = xmlModulePlatformOpen ( name ) ;
2005-01-04 15:10:22 +00:00
2005-01-04 17:50:14 +00:00
if ( module - > handle = = NULL ) {
xmlFree ( module ) ;
__xmlRaiseError ( NULL , NULL , NULL , NULL , NULL , XML_FROM_MODULE ,
XML_MODULE_OPEN , XML_ERR_FATAL , NULL , 0 , 0 ,
name , NULL , 0 , 0 , " failed to open %s \n " , name ) ;
2005-07-28 23:49:35 +00:00
return ( NULL ) ;
2005-01-04 17:50:14 +00:00
}
2005-01-04 15:10:22 +00:00
2005-01-04 17:50:14 +00:00
module - > name = xmlStrdup ( ( const xmlChar * ) name ) ;
return ( module ) ;
2005-01-04 15:10:22 +00:00
}
2005-01-04 17:50:14 +00:00
/**
* xmlModuleSymbol :
* @ module : the module
* @ name : the name of the symbol
2005-01-04 20:18:14 +00:00
* @ symbol : the resulting symbol address
2005-01-04 17:50:14 +00:00
*
* Lookup for a symbol address in the given module
2012-08-13 17:39:06 +08:00
* NOTE : that due to portability issues , behaviour can only be
* guaranteed with @ name using ASCII . We canot guarantee that
* an UTF - 8 string would work , which is why name is a const char *
* and not a const xmlChar * .
2005-01-04 17:50:14 +00:00
*
2005-01-04 20:18:14 +00:00
* Returns 0 if the symbol was found , or - 1 in case of error
2005-01-04 17:50:14 +00:00
*/
2005-01-04 20:18:14 +00:00
int
xmlModuleSymbol ( xmlModulePtr module , const char * name , void * * symbol )
2005-01-04 15:10:22 +00:00
{
2005-01-04 20:18:14 +00:00
int rc = - 1 ;
2012-09-11 13:26:36 +08:00
2014-02-18 11:47:43 +08:00
if ( ( NULL = = module ) | | ( symbol = = NULL ) | | ( name = = NULL ) ) {
2005-01-04 17:50:14 +00:00
__xmlRaiseError ( NULL , NULL , NULL , NULL , NULL , XML_FROM_MODULE ,
XML_MODULE_OPEN , XML_ERR_FATAL , NULL , 0 , 0 ,
2005-01-04 20:18:14 +00:00
NULL , NULL , 0 , 0 , " null parameter \n " ) ;
return rc ;
2005-01-04 17:50:14 +00:00
}
2005-01-04 15:10:22 +00:00
2005-01-04 20:18:14 +00:00
rc = xmlModulePlatformSymbol ( module - > handle , name , symbol ) ;
2005-01-04 15:10:22 +00:00
2005-01-04 20:18:14 +00:00
if ( rc = = - 1 ) {
2005-01-04 17:50:14 +00:00
__xmlRaiseError ( NULL , NULL , NULL , NULL , NULL , XML_FROM_MODULE ,
XML_MODULE_OPEN , XML_ERR_FATAL , NULL , 0 , 0 ,
2005-01-04 20:18:14 +00:00
name , NULL , 0 , 0 ,
" failed to find symbol: %s \n " ,
( name = = NULL ? " NULL " : name ) ) ;
return rc ;
2005-01-04 17:50:14 +00:00
}
2005-01-04 15:10:22 +00:00
2005-01-04 20:18:14 +00:00
return rc ;
2005-01-04 15:10:22 +00:00
}
2005-01-04 17:50:14 +00:00
/**
* xmlModuleClose :
* @ module : the module handle
*
* The close operations unload the associated module and free the
* data associated to the module .
*
* Returns 0 in case of success , - 1 in case of argument error and - 2
* if the module could not be closed / unloaded .
*/
int
xmlModuleClose ( xmlModulePtr module )
2005-01-04 15:10:22 +00:00
{
2005-01-04 17:50:14 +00:00
int rc ;
2005-01-04 15:10:22 +00:00
2005-01-04 17:50:14 +00:00
if ( NULL = = module ) {
__xmlRaiseError ( NULL , NULL , NULL , NULL , NULL , XML_FROM_MODULE ,
2005-01-04 20:18:14 +00:00
XML_MODULE_CLOSE , XML_ERR_FATAL , NULL , 0 , 0 ,
NULL , NULL , 0 , 0 , " null module pointer \n " ) ;
2005-01-04 17:50:14 +00:00
return - 1 ;
}
2005-01-04 15:10:22 +00:00
2005-01-04 17:50:14 +00:00
rc = xmlModulePlatformClose ( module - > handle ) ;
2005-01-04 15:10:22 +00:00
2005-01-04 17:50:14 +00:00
if ( rc ! = 0 ) {
__xmlRaiseError ( NULL , NULL , NULL , NULL , NULL , XML_FROM_MODULE ,
2005-01-04 20:18:14 +00:00
XML_MODULE_CLOSE , XML_ERR_FATAL , NULL , 0 , 0 ,
2005-01-04 17:50:14 +00:00
( const char * ) module - > name , NULL , 0 , 0 ,
2005-01-04 20:18:14 +00:00
" failed to close: %s \n " , module - > name ) ;
2005-01-04 17:50:14 +00:00
return - 2 ;
}
rc = xmlModuleFree ( module ) ;
return ( rc ) ;
2005-01-04 15:10:22 +00:00
}
2005-01-04 17:50:14 +00:00
/**
* xmlModuleFree :
* @ module : the module handle
*
* The free operations free the data associated to the module
* but does not unload the associated shared library which may still
* be in use .
*
* Returns 0 in case of success , - 1 in case of argument error
*/
int
xmlModuleFree ( xmlModulePtr module )
2005-01-04 15:10:22 +00:00
{
2005-01-04 17:50:14 +00:00
if ( NULL = = module ) {
__xmlRaiseError ( NULL , NULL , NULL , NULL , NULL , XML_FROM_MODULE ,
2005-07-28 23:49:35 +00:00
XML_MODULE_CLOSE , XML_ERR_FATAL , NULL , 0 , NULL ,
2005-01-04 20:18:14 +00:00
NULL , NULL , 0 , 0 , " null module pointer \n " ) ;
2005-01-04 17:50:14 +00:00
return - 1 ;
}
2005-01-04 15:10:22 +00:00
2005-01-04 17:50:14 +00:00
xmlFree ( module - > name ) ;
xmlFree ( module ) ;
2005-01-04 15:10:22 +00:00
2005-01-04 17:50:14 +00:00
return ( 0 ) ;
2005-01-04 15:10:22 +00:00
}
2008-02-08 10:49:46 +00:00
# if defined(HAVE_DLOPEN) && !defined(_WIN32)
2005-01-13 11:25:15 +00:00
# ifdef HAVE_DLFCN_H
2005-01-04 15:10:22 +00:00
# include <dlfcn.h>
2005-01-13 11:25:15 +00:00
# endif
2005-01-04 15:10:22 +00:00
2005-10-28 14:54:17 +00:00
# ifndef RTLD_GLOBAL /* For Tru64 UNIX 4.0 */
# define RTLD_GLOBAL 0
# endif
2005-01-04 17:50:14 +00:00
/**
2005-01-04 15:10:22 +00:00
* xmlModulePlatformOpen :
2005-01-04 17:50:14 +00:00
* @ name : path to the module
*
2005-01-04 15:10:22 +00:00
* returns a handle on success , and zero on error .
2005-01-04 17:50:14 +00:00
*/
2005-01-04 15:10:22 +00:00
2005-01-04 17:50:14 +00:00
static void *
xmlModulePlatformOpen ( const char * name )
2005-01-04 15:10:22 +00:00
{
2005-01-04 20:18:14 +00:00
return dlopen ( name , RTLD_GLOBAL | RTLD_NOW ) ;
2005-01-04 15:10:22 +00:00
}
/*
* xmlModulePlatformClose :
2005-01-04 17:50:14 +00:00
* @ handle : handle to the module
*
2005-01-04 15:10:22 +00:00
* returns 0 on success , and non - zero on error .
2005-01-04 17:50:14 +00:00
*/
2005-01-04 15:10:22 +00:00
2005-01-04 17:50:14 +00:00
static int
xmlModulePlatformClose ( void * handle )
2005-01-04 15:10:22 +00:00
{
2005-01-04 20:18:14 +00:00
return dlclose ( handle ) ;
2005-01-04 15:10:22 +00:00
}
/*
* xmlModulePlatformSymbol :
2005-01-04 20:18:14 +00:00
* http : //www.opengroup.org/onlinepubs/009695399/functions/dlsym.html
* returns 0 on success and the loaded symbol in result , and - 1 on error .
2005-01-04 17:50:14 +00:00
*/
2005-01-04 15:10:22 +00:00
2005-01-04 20:18:14 +00:00
static int
xmlModulePlatformSymbol ( void * handle , const char * name , void * * symbol )
2005-01-04 15:10:22 +00:00
{
2005-01-04 20:18:14 +00:00
* symbol = dlsym ( handle , name ) ;
if ( dlerror ( ) ! = NULL ) {
return - 1 ;
}
return 0 ;
2005-01-04 15:10:22 +00:00
}
2005-03-10 10:37:28 +00:00
# else /* ! HAVE_DLOPEN */
2005-01-04 15:10:22 +00:00
2005-01-04 17:50:14 +00:00
# ifdef HAVE_SHLLOAD /* HAVE_SHLLOAD */
2005-01-13 11:25:15 +00:00
# ifdef HAVE_DL_H
# include <dl.h>
# endif
2005-01-04 15:10:22 +00:00
/*
* xmlModulePlatformOpen :
* returns a handle on success , and zero on error .
2005-01-04 17:50:14 +00:00
*/
2005-01-04 15:10:22 +00:00
2005-01-04 17:50:14 +00:00
static void *
xmlModulePlatformOpen ( const char * name )
2005-01-04 15:10:22 +00:00
{
2005-01-04 20:18:14 +00:00
return shl_load ( name , BIND_IMMEDIATE , 0L ) ;
2005-01-04 15:10:22 +00:00
}
/*
* xmlModulePlatformClose :
* returns 0 on success , and non - zero on error .
2005-01-04 17:50:14 +00:00
*/
2005-01-04 15:10:22 +00:00
2005-01-04 17:50:14 +00:00
static int
xmlModulePlatformClose ( void * handle )
2005-01-04 15:10:22 +00:00
{
2005-01-04 20:18:14 +00:00
return shl_unload ( handle ) ;
2005-01-04 15:10:22 +00:00
}
/*
* xmlModulePlatformSymbol :
2005-01-04 20:18:14 +00:00
* http : //docs.hp.com/en/B2355-90683/shl_load.3X.html
* returns 0 on success and the loaded symbol in result , and - 1 on error .
2005-01-04 17:50:14 +00:00
*/
2005-01-04 15:10:22 +00:00
2005-01-04 20:18:14 +00:00
static int
xmlModulePlatformSymbol ( void * handle , const char * name , void * * symbol )
2005-01-04 15:10:22 +00:00
{
2005-01-04 17:50:14 +00:00
int rc ;
errno = 0 ;
2005-10-28 14:54:17 +00:00
rc = shl_findsym ( & handle , name , TYPE_UNDEFINED , symbol ) ;
2005-01-04 20:18:14 +00:00
return rc ;
2005-01-04 15:10:22 +00:00
}
# endif /* HAVE_SHLLOAD */
2005-03-10 10:37:28 +00:00
# endif /* ! HAVE_DLOPEN */
2005-01-04 15:10:22 +00:00
# ifdef _WIN32
# include <windows.h>
/*
* xmlModulePlatformOpen :
* returns a handle on success , and zero on error .
2005-01-04 17:50:14 +00:00
*/
2005-01-04 15:10:22 +00:00
2005-01-04 17:50:14 +00:00
static void *
xmlModulePlatformOpen ( const char * name )
2005-01-04 15:10:22 +00:00
{
2012-08-13 17:39:06 +08:00
return LoadLibraryA ( name ) ;
2005-01-04 15:10:22 +00:00
}
/*
* xmlModulePlatformClose :
* returns 0 on success , and non - zero on error .
2005-01-04 17:50:14 +00:00
*/
2005-01-04 15:10:22 +00:00
2005-01-04 17:50:14 +00:00
static int
xmlModulePlatformClose ( void * handle )
2005-01-04 15:10:22 +00:00
{
2005-01-04 17:50:14 +00:00
int rc ;
rc = FreeLibrary ( handle ) ;
return ( 0 = = rc ) ;
2005-01-04 15:10:22 +00:00
}
/*
* xmlModulePlatformSymbol :
2005-01-04 20:18:14 +00:00
* http : //msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/getprocaddress.asp
* returns 0 on success and the loaded symbol in result , and - 1 on error .
2005-01-04 17:50:14 +00:00
*/
2005-01-04 15:10:22 +00:00
2005-01-04 20:18:14 +00:00
static int
xmlModulePlatformSymbol ( void * handle , const char * name , void * * symbol )
2005-01-04 15:10:22 +00:00
{
2012-08-17 11:04:24 +08:00
# ifdef _WIN32_WCE
/*
* GetProcAddressA seems only available on WinCE
*/
2012-08-13 17:39:06 +08:00
* symbol = GetProcAddressA ( handle , name ) ;
2012-08-17 11:04:24 +08:00
# else
* symbol = GetProcAddress ( handle , name ) ;
# endif
2005-01-04 20:18:14 +00:00
return ( NULL = = * symbol ) ? - 1 : 0 ;
2005-01-04 15:10:22 +00:00
}
# endif /* _WIN32 */
# ifdef HAVE_BEOS
# include <kernel/image.h>
/*
* xmlModulePlatformOpen :
* beos api info : http : //www.beunited.org/bebook/The%20Kernel%20Kit/Images.html
* returns a handle on success , and zero on error .
2005-01-04 17:50:14 +00:00
*/
2005-01-04 15:10:22 +00:00
2005-01-04 17:50:14 +00:00
static void *
xmlModulePlatformOpen ( const char * name )
2005-01-04 15:10:22 +00:00
{
2005-01-04 20:18:14 +00:00
return ( void * ) load_add_on ( name ) ;
2005-01-04 15:10:22 +00:00
}
/*
* xmlModulePlatformClose :
* beos api info : http : //www.beunited.org/bebook/The%20Kernel%20Kit/Images.html
* returns 0 on success , and non - zero on error .
2005-01-04 17:50:14 +00:00
*/
2005-01-04 15:10:22 +00:00
2005-01-04 17:50:14 +00:00
static int
xmlModulePlatformClose ( void * handle )
2005-01-04 15:10:22 +00:00
{
2005-01-04 17:50:14 +00:00
status_t rc ;
2005-01-04 15:10:22 +00:00
2005-01-04 17:50:14 +00:00
rc = unload_add_on ( ( image_id ) handle ) ;
if ( rc = = B_OK )
return 0 ;
else
return - 1 ;
2005-01-04 15:10:22 +00:00
}
/*
* xmlModulePlatformSymbol :
* beos api info : http : //www.beunited.org/bebook/The%20Kernel%20Kit/Images.html
2005-01-04 20:18:14 +00:00
* returns 0 on success and the loaded symbol in result , and - 1 on error .
2005-01-04 17:50:14 +00:00
*/
2005-01-04 15:10:22 +00:00
2005-01-04 20:18:14 +00:00
static int
xmlModulePlatformSymbol ( void * handle , const char * name , void * * symbol )
2005-01-04 15:10:22 +00:00
{
2005-01-04 17:50:14 +00:00
status_t rc ;
2005-01-04 15:10:22 +00:00
2005-01-04 20:18:14 +00:00
rc = get_image_symbol ( ( image_id ) handle , name , B_SYMBOL_TYPE_ANY , symbol ) ;
2005-01-04 15:10:22 +00:00
2005-01-04 20:18:14 +00:00
return ( rc = = B_OK ) ? 0 : - 1 ;
2005-01-04 15:10:22 +00:00
}
# endif /* HAVE_BEOS */
# ifdef HAVE_OS2
# include <os2.h>
/*
* xmlModulePlatformOpen :
* os2 api info : http : //www.edm2.com/os2api/Dos/DosLoadModule.html
* returns a handle on success , and zero on error .
2005-01-04 17:50:14 +00:00
*/
2005-01-04 15:10:22 +00:00
2005-01-04 17:50:14 +00:00
static void *
xmlModulePlatformOpen ( const char * name )
2005-01-04 15:10:22 +00:00
{
2005-01-04 20:18:14 +00:00
char errbuf [ 256 ] ;
2005-01-04 17:50:14 +00:00
void * handle ;
int rc ;
2005-01-04 15:10:22 +00:00
2005-01-04 20:18:14 +00:00
rc = DosLoadModule ( errbuf , sizeof ( errbuf ) - 1 , name , & handle ) ;
2005-01-04 15:10:22 +00:00
2005-01-04 17:50:14 +00:00
if ( rc )
return 0 ;
else
return ( handle ) ;
2005-01-04 15:10:22 +00:00
}
/*
* xmlModulePlatformClose :
* os2 api info : http : //www.edm2.com/os2api/Dos/DosFreeModule.html
* returns 0 on success , and non - zero on error .
2005-01-04 17:50:14 +00:00
*/
2005-01-04 15:10:22 +00:00
2005-01-04 17:50:14 +00:00
static int
xmlModulePlatformClose ( void * handle )
2005-01-04 15:10:22 +00:00
{
2005-01-04 20:18:14 +00:00
return DosFreeModule ( handle ) ;
2005-01-04 15:10:22 +00:00
}
/*
* xmlModulePlatformSymbol :
* os2 api info : http : //www.edm2.com/os2api/Dos/DosQueryProcAddr.html
2005-01-04 20:18:14 +00:00
* returns 0 on success and the loaded symbol in result , and - 1 on error .
2005-01-04 17:50:14 +00:00
*/
2005-01-04 15:10:22 +00:00
2005-01-04 20:18:14 +00:00
static int
xmlModulePlatformSymbol ( void * handle , const char * name , void * * symbol )
2005-01-04 15:10:22 +00:00
{
2005-01-04 17:50:14 +00:00
int rc ;
2005-01-04 15:10:22 +00:00
2005-01-04 20:18:14 +00:00
rc = DosQueryProcAddr ( handle , 0 , name , symbol ) ;
2005-01-04 17:50:14 +00:00
2005-01-04 20:18:14 +00:00
return ( rc = = NO_ERROR ) ? 0 : - 1 ;
2005-01-04 15:10:22 +00:00
}
# endif /* HAVE_OS2 */
2005-04-01 13:11:58 +00:00
# define bottom_xmlmodule
# include "elfgcchack.h"
2005-01-04 15:10:22 +00:00
# endif /* LIBXML_MODULES_ENABLED */