2005-01-04 18:10:22 +03:00
/*
2005-01-04 20:50:14 +03:00
* xmlmodule . c : basic API for dynamic module loading added 2.6 .17
2005-01-04 18:10:22 +03:00
*
* See Copyright for the status of this software .
*
* joelwreed @ comcast . net
2005-01-04 23:18:14 +03:00
*
* http : //www.fortran-2000.com/ArnaudRecipes/sharedlib.html
2005-01-04 18:10:22 +03:00
*/
2017-08-28 15:30:43 +03:00
/* In order RTLD_GLOBAL and RTLD_NOW to be defined on zOS */
# if defined(__MVS__)
# define _UNIX03_SOURCE
# endif
2005-01-04 18:10:22 +03:00
# define IN_LIBXML
# include "libxml.h"
# include <string.h>
2023-09-20 19:54:39 +03:00
# include <libxml/xmlmodule.h>
2005-01-04 18:10:22 +03:00
# include <libxml/xmlmemory.h>
# include <libxml/xmlerror.h>
2023-09-20 19:54:39 +03:00
# include <libxml/xmlstring.h>
2005-01-04 18:10:22 +03:00
2022-08-26 02:22:33 +03:00
# include "private/error.h"
2005-01-04 18:10:22 +03:00
# ifdef LIBXML_MODULES_ENABLED
struct _xmlModule {
2005-01-04 20:50:14 +03:00
unsigned char * name ;
void * handle ;
2005-01-04 18:10:22 +03:00
} ;
2005-01-04 20:50:14 +03:00
static void * xmlModulePlatformOpen ( const char * name ) ;
static int xmlModulePlatformClose ( void * handle ) ;
2005-01-04 23:18:14 +03:00
static int xmlModulePlatformSymbol ( void * handle , const char * name , void * * result ) ;
2005-01-04 18:10:22 +03:00
/************************************************************************
* *
2012-09-11 09:26:36 +04:00
* module memory error handler *
2005-01-04 18:10:22 +03:00
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-01-04 20:50:14 +03:00
/**
* xmlModuleOpen :
* @ name : the module name
2005-01-05 00:50:05 +03:00
* @ options : a set of xmlModuleOption
2005-01-04 20:50:14 +03:00
*
* Opens a module / shared library given its name or path
2012-08-13 13:39:06 +04:00
* NOTE : that due to portability issues , behaviour can only be
2019-09-30 18:04:54 +03:00
* guaranteed with @ name using ASCII . We cannot guarantee that
2012-08-13 13:39:06 +04:00
* an UTF - 8 string would work , which is why name is a const char *
* and not a const xmlChar * .
2005-01-05 00:50:05 +03:00
* TODO : options are not yet implemented .
2005-01-04 20:50:14 +03:00
*
* Returns a handle for the module or NULL in case of error
*/
xmlModulePtr
2005-01-05 00:50:05 +03:00
xmlModuleOpen ( const char * name , int options ATTRIBUTE_UNUSED )
2005-01-04 18:10:22 +03:00
{
2005-01-04 20:50:14 +03:00
xmlModulePtr module ;
2005-01-04 18:10:22 +03:00
2005-01-04 20:50:14 +03:00
module = ( xmlModulePtr ) xmlMalloc ( sizeof ( xmlModule ) ) ;
2023-12-18 23:32:49 +03:00
if ( module = = NULL )
2005-01-04 20:50:14 +03:00
return ( NULL ) ;
2005-01-04 18:10:22 +03:00
2005-01-04 20:50:14 +03:00
memset ( module , 0 , sizeof ( xmlModule ) ) ;
2005-01-04 18:10:22 +03:00
2005-01-04 20:50:14 +03:00
module - > handle = xmlModulePlatformOpen ( name ) ;
2005-01-04 18:10:22 +03:00
2005-01-04 20:50:14 +03:00
if ( module - > handle = = NULL ) {
xmlFree ( module ) ;
2005-07-29 03:49:35 +04:00
return ( NULL ) ;
2005-01-04 20:50:14 +03:00
}
2005-01-04 18:10:22 +03:00
2005-01-04 20:50:14 +03:00
module - > name = xmlStrdup ( ( const xmlChar * ) name ) ;
return ( module ) ;
2005-01-04 18:10:22 +03:00
}
2005-01-04 20:50:14 +03:00
/**
* xmlModuleSymbol :
* @ module : the module
* @ name : the name of the symbol
2005-01-04 23:18:14 +03:00
* @ symbol : the resulting symbol address
2005-01-04 20:50:14 +03:00
*
* Lookup for a symbol address in the given module
2012-08-13 13:39:06 +04:00
* NOTE : that due to portability issues , behaviour can only be
2019-09-30 18:04:54 +03:00
* guaranteed with @ name using ASCII . We cannot guarantee that
2012-08-13 13:39:06 +04:00
* an UTF - 8 string would work , which is why name is a const char *
* and not a const xmlChar * .
2005-01-04 20:50:14 +03:00
*
2005-01-04 23:18:14 +03:00
* Returns 0 if the symbol was found , or - 1 in case of error
2005-01-04 20:50:14 +03:00
*/
2005-01-04 23:18:14 +03:00
int
xmlModuleSymbol ( xmlModulePtr module , const char * name , void * * symbol )
2005-01-04 18:10:22 +03:00
{
2005-01-04 23:18:14 +03:00
int rc = - 1 ;
2012-09-11 09:26:36 +04:00
2023-12-18 23:32:49 +03:00
if ( ( NULL = = module ) | | ( symbol = = NULL ) | | ( name = = NULL ) )
2005-01-04 23:18:14 +03:00
return rc ;
2005-01-04 18:10:22 +03:00
2005-01-04 23:18:14 +03:00
rc = xmlModulePlatformSymbol ( module - > handle , name , symbol ) ;
2005-01-04 18:10:22 +03:00
2023-12-18 23:32:49 +03:00
if ( rc = = - 1 )
2005-01-04 23:18:14 +03:00
return rc ;
2005-01-04 18:10:22 +03:00
2005-01-04 23:18:14 +03:00
return rc ;
2005-01-04 18:10:22 +03:00
}
2005-01-04 20:50:14 +03: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 18:10:22 +03:00
{
2005-01-04 20:50:14 +03:00
int rc ;
2005-01-04 18:10:22 +03:00
2023-12-18 23:32:49 +03:00
if ( NULL = = module )
2005-01-04 20:50:14 +03:00
return - 1 ;
2005-01-04 18:10:22 +03:00
2005-01-04 20:50:14 +03:00
rc = xmlModulePlatformClose ( module - > handle ) ;
2005-01-04 18:10:22 +03:00
2023-12-18 23:32:49 +03:00
if ( rc ! = 0 )
2005-01-04 20:50:14 +03:00
return - 2 ;
rc = xmlModuleFree ( module ) ;
return ( rc ) ;
2005-01-04 18:10:22 +03:00
}
2005-01-04 20:50:14 +03: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 18:10:22 +03:00
{
2023-12-18 23:32:49 +03:00
if ( NULL = = module )
2005-01-04 20:50:14 +03:00
return - 1 ;
2005-01-04 18:10:22 +03:00
2005-01-04 20:50:14 +03:00
xmlFree ( module - > name ) ;
xmlFree ( module ) ;
2005-01-04 18:10:22 +03:00
2005-01-04 20:50:14 +03:00
return ( 0 ) ;
2005-01-04 18:10:22 +03:00
}
2008-02-08 13:49:46 +03:00
# if defined(HAVE_DLOPEN) && !defined(_WIN32)
2005-01-13 14:25:15 +03:00
# ifdef HAVE_DLFCN_H
2005-01-04 18:10:22 +03:00
# include <dlfcn.h>
2005-01-13 14:25:15 +03:00
# endif
2005-01-04 18:10:22 +03:00
2005-10-28 18:54:17 +04:00
# ifndef RTLD_GLOBAL /* For Tru64 UNIX 4.0 */
# define RTLD_GLOBAL 0
# endif
2005-01-04 20:50:14 +03:00
/**
2005-01-04 18:10:22 +03:00
* xmlModulePlatformOpen :
2005-01-04 20:50:14 +03:00
* @ name : path to the module
*
2005-01-04 18:10:22 +03:00
* returns a handle on success , and zero on error .
2005-01-04 20:50:14 +03:00
*/
2005-01-04 18:10:22 +03:00
2005-01-04 20:50:14 +03:00
static void *
xmlModulePlatformOpen ( const char * name )
2005-01-04 18:10:22 +03:00
{
2005-01-04 23:18:14 +03:00
return dlopen ( name , RTLD_GLOBAL | RTLD_NOW ) ;
2005-01-04 18:10:22 +03:00
}
/*
* xmlModulePlatformClose :
2005-01-04 20:50:14 +03:00
* @ handle : handle to the module
*
2005-01-04 18:10:22 +03:00
* returns 0 on success , and non - zero on error .
2005-01-04 20:50:14 +03:00
*/
2005-01-04 18:10:22 +03:00
2005-01-04 20:50:14 +03:00
static int
xmlModulePlatformClose ( void * handle )
2005-01-04 18:10:22 +03:00
{
2005-01-04 23:18:14 +03:00
return dlclose ( handle ) ;
2005-01-04 18:10:22 +03:00
}
/*
* xmlModulePlatformSymbol :
2005-01-04 23:18:14 +03: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 20:50:14 +03:00
*/
2005-01-04 18:10:22 +03:00
2005-01-04 23:18:14 +03:00
static int
xmlModulePlatformSymbol ( void * handle , const char * name , void * * symbol )
2005-01-04 18:10:22 +03:00
{
2005-01-04 23:18:14 +03:00
* symbol = dlsym ( handle , name ) ;
if ( dlerror ( ) ! = NULL ) {
return - 1 ;
}
return 0 ;
2005-01-04 18:10:22 +03:00
}
2005-03-10 13:37:28 +03:00
# else /* ! HAVE_DLOPEN */
2005-01-04 18:10:22 +03:00
2005-01-04 20:50:14 +03:00
# ifdef HAVE_SHLLOAD /* HAVE_SHLLOAD */
2005-01-13 14:25:15 +03:00
# ifdef HAVE_DL_H
# include <dl.h>
# endif
2005-01-04 18:10:22 +03:00
/*
* xmlModulePlatformOpen :
* returns a handle on success , and zero on error .
2005-01-04 20:50:14 +03:00
*/
2005-01-04 18:10:22 +03:00
2005-01-04 20:50:14 +03:00
static void *
xmlModulePlatformOpen ( const char * name )
2005-01-04 18:10:22 +03:00
{
2005-01-04 23:18:14 +03:00
return shl_load ( name , BIND_IMMEDIATE , 0L ) ;
2005-01-04 18:10:22 +03:00
}
/*
* xmlModulePlatformClose :
* returns 0 on success , and non - zero on error .
2005-01-04 20:50:14 +03:00
*/
2005-01-04 18:10:22 +03:00
2005-01-04 20:50:14 +03:00
static int
xmlModulePlatformClose ( void * handle )
2005-01-04 18:10:22 +03:00
{
2005-01-04 23:18:14 +03:00
return shl_unload ( handle ) ;
2005-01-04 18:10:22 +03:00
}
/*
* xmlModulePlatformSymbol :
2005-01-04 23:18:14 +03: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 20:50:14 +03:00
*/
2005-01-04 18:10:22 +03:00
2005-01-04 23:18:14 +03:00
static int
xmlModulePlatformSymbol ( void * handle , const char * name , void * * symbol )
2005-01-04 18:10:22 +03:00
{
2005-01-04 20:50:14 +03:00
int rc ;
errno = 0 ;
2005-10-28 18:54:17 +04:00
rc = shl_findsym ( & handle , name , TYPE_UNDEFINED , symbol ) ;
2005-01-04 23:18:14 +03:00
return rc ;
2005-01-04 18:10:22 +03:00
}
# endif /* HAVE_SHLLOAD */
2005-03-10 13:37:28 +03:00
# endif /* ! HAVE_DLOPEN */
2005-01-04 18:10:22 +03:00
2022-03-01 00:42:10 +03:00
# if defined(_WIN32)
2005-01-04 18:10:22 +03:00
2017-10-09 01:20:01 +03:00
# define WIN32_LEAN_AND_MEAN
2005-01-04 18:10:22 +03:00
# include <windows.h>
/*
* xmlModulePlatformOpen :
* returns a handle on success , and zero on error .
2005-01-04 20:50:14 +03:00
*/
2005-01-04 18:10:22 +03:00
2005-01-04 20:50:14 +03:00
static void *
xmlModulePlatformOpen ( const char * name )
2005-01-04 18:10:22 +03:00
{
2012-08-13 13:39:06 +04:00
return LoadLibraryA ( name ) ;
2005-01-04 18:10:22 +03:00
}
/*
* xmlModulePlatformClose :
* returns 0 on success , and non - zero on error .
2005-01-04 20:50:14 +03:00
*/
2005-01-04 18:10:22 +03:00
2005-01-04 20:50:14 +03:00
static int
xmlModulePlatformClose ( void * handle )
2005-01-04 18:10:22 +03:00
{
2005-01-04 20:50:14 +03:00
int rc ;
rc = FreeLibrary ( handle ) ;
return ( 0 = = rc ) ;
2005-01-04 18:10:22 +03:00
}
/*
* xmlModulePlatformSymbol :
2005-01-04 23:18:14 +03: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 20:50:14 +03:00
*/
2005-01-04 18:10:22 +03:00
2005-01-04 23:18:14 +03:00
static int
xmlModulePlatformSymbol ( void * handle , const char * name , void * * symbol )
2005-01-04 18:10:22 +03:00
{
2022-09-04 17:41:43 +03:00
XML_IGNORE_FPTR_CAST_WARNINGS
2012-08-17 07:04:24 +04:00
* symbol = GetProcAddress ( handle , name ) ;
2005-01-04 23:18:14 +03:00
return ( NULL = = * symbol ) ? - 1 : 0 ;
2017-11-12 19:28:12 +03:00
XML_POP_WARNINGS
2005-01-04 18:10:22 +03:00
}
# endif /* _WIN32 */
# endif /* LIBXML_MODULES_ENABLED */