root/third_party/libxml/src/xmlmodule.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. xmlModuleErrMemory
  2. xmlModuleOpen
  3. xmlModuleSymbol
  4. xmlModuleClose
  5. xmlModuleFree
  6. xmlModulePlatformOpen
  7. xmlModulePlatformClose
  8. xmlModulePlatformSymbol
  9. xmlModulePlatformOpen
  10. xmlModulePlatformClose
  11. xmlModulePlatformSymbol
  12. xmlModulePlatformOpen
  13. xmlModulePlatformClose
  14. xmlModulePlatformSymbol
  15. xmlModulePlatformOpen
  16. xmlModulePlatformClose
  17. xmlModulePlatformSymbol
  18. xmlModulePlatformOpen
  19. xmlModulePlatformClose
  20. xmlModulePlatformSymbol

/*
 * xmlmodule.c : basic API for dynamic module loading added 2.6.17
 *
 * See Copyright for the status of this software.
 *
 * joelwreed@comcast.net
 *
 * http://www.fortran-2000.com/ArnaudRecipes/sharedlib.html
 */

#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 {
    unsigned char *name;
    void *handle;
};

static void *xmlModulePlatformOpen(const char *name);
static int xmlModulePlatformClose(void *handle);
static int xmlModulePlatformSymbol(void *handle, const char *name, void **result);

/************************************************************************
 *                                                                      *
 *              module memory error handler                             *
 *                                                                      *
 ************************************************************************/

/**
 * xmlModuleErrMemory:
 * @extra:  extra information
 *
 * Handle an out of memory condition
 */
static void
xmlModuleErrMemory(xmlModulePtr module, const char *extra)
{
    const char *name = NULL;

    if (module != NULL) {
        name = (const char *) module->name;
    }

    __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);
}

/**
 * xmlModuleOpen:
 * @name: the module name
 * @options: a set of xmlModuleOption
 *
 * Opens a module/shared library given its name or path
 * TODO: options are not yet implemented.
 *
 * Returns a handle for the module or NULL in case of error
 */
xmlModulePtr
xmlModuleOpen(const char *name, int options ATTRIBUTE_UNUSED)
{
    xmlModulePtr module;

    module = (xmlModulePtr) xmlMalloc(sizeof(xmlModule));
    if (module == NULL) {
        xmlModuleErrMemory(NULL, "creating module");
        return (NULL);
    }

    memset(module, 0, sizeof(xmlModule));

    module->handle = xmlModulePlatformOpen(name);

    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);
        return(NULL);
    }

    module->name = xmlStrdup((const xmlChar *) name);
    return (module);
}

/**
 * xmlModuleSymbol:
 * @module: the module
 * @name: the name of the symbol
 * @symbol: the resulting symbol address
 *
 * Lookup for a symbol address in the given module
 *
 * Returns 0 if the symbol was found, or -1 in case of error
 */
int
xmlModuleSymbol(xmlModulePtr module, const char *name, void **symbol)
{
    int rc = -1;
        
    if ((NULL == module) || (symbol == NULL)) {
        __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
                        XML_MODULE_OPEN, XML_ERR_FATAL, NULL, 0, 0,
                        NULL, NULL, 0, 0, "null parameter\n");
        return rc;
    }

    rc = xmlModulePlatformSymbol(module->handle, name, symbol);

    if (rc == -1) {
        __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
                        XML_MODULE_OPEN, XML_ERR_FATAL, NULL, 0, 0,
                        name, NULL, 0, 0,
                        "failed to find symbol: %s\n",
                        (name == NULL ? "NULL" : name));
        return rc;
    }

    return rc;
}

/**
 * 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)
{
    int rc;

    if (NULL == module) {
        __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
                        XML_MODULE_CLOSE, XML_ERR_FATAL, NULL, 0, 0,
                        NULL, NULL, 0, 0, "null module pointer\n");
        return -1;
    }

    rc = xmlModulePlatformClose(module->handle);

    if (rc != 0) {
        __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
                        XML_MODULE_CLOSE, XML_ERR_FATAL, NULL, 0, 0,
                        (const char *) module->name, NULL, 0, 0,
                        "failed to close: %s\n", module->name);
        return -2;
    }

    rc = xmlModuleFree(module);
    return (rc);
}

/**
 * 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)
{
    if (NULL == module) {
        __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
                        XML_MODULE_CLOSE, XML_ERR_FATAL, NULL, 0, NULL,
                        NULL, NULL, 0, 0, "null module pointer\n");
        return -1;
    }

    xmlFree(module->name);
    xmlFree(module);

    return (0);
}

#if defined(HAVE_DLOPEN) && !defined(_WIN32)
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#endif

#ifndef RTLD_GLOBAL            /* For Tru64 UNIX 4.0 */
#define RTLD_GLOBAL 0
#endif

/**
 * xmlModulePlatformOpen:
 * @name: path to the module
 *
 * returns a handle on success, and zero on error.
 */

static void *
xmlModulePlatformOpen(const char *name)
{
    return dlopen(name, RTLD_GLOBAL | RTLD_NOW);
}

/*
 * xmlModulePlatformClose:
 * @handle: handle to the module
 *
 * returns 0 on success, and non-zero on error.
 */

static int
xmlModulePlatformClose(void *handle)
{
    return dlclose(handle);
}

/*
 * xmlModulePlatformSymbol:
 * http://www.opengroup.org/onlinepubs/009695399/functions/dlsym.html
 * returns 0 on success and the loaded symbol in result, and -1 on error.
 */

static int
xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
{
    *symbol = dlsym(handle, name);
    if (dlerror() != NULL) {
        return -1;
    }
    return 0;
}

#else /* ! HAVE_DLOPEN */

#ifdef HAVE_SHLLOAD             /* HAVE_SHLLOAD */
#ifdef HAVE_DL_H
#include <dl.h>
#endif
/*
 * xmlModulePlatformOpen:
 * returns a handle on success, and zero on error.
 */

static void *
xmlModulePlatformOpen(const char *name)
{
    return shl_load(name, BIND_IMMEDIATE, 0L);
}

/*
 * xmlModulePlatformClose:
 * returns 0 on success, and non-zero on error.
 */

static int
xmlModulePlatformClose(void *handle)
{
    return shl_unload(handle);
}

/*
 * xmlModulePlatformSymbol:
 * 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.
 */

static int
xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
{
    int rc;

    errno = 0;
    rc = shl_findsym(&handle, name, TYPE_UNDEFINED, symbol);
    return rc;
}

#endif /* HAVE_SHLLOAD */
#endif /* ! HAVE_DLOPEN */

#ifdef _WIN32

#include <windows.h>

/*
 * xmlModulePlatformOpen:
 * returns a handle on success, and zero on error.
 */

static void *
xmlModulePlatformOpen(const char *name)
{
    return LoadLibraryA(name);
}

/*
 * xmlModulePlatformClose:
 * returns 0 on success, and non-zero on error.
 */

static int
xmlModulePlatformClose(void *handle)
{
    int rc;

    rc = FreeLibrary(handle);
    return (0 == rc);
}

/*
 * xmlModulePlatformSymbol:
 * 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.
 */

static int
xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
{
    *symbol = GetProcAddress(handle, name);
    return (NULL == *symbol) ? -1 : 0;
}

#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.
 */

static void *
xmlModulePlatformOpen(const char *name)
{
    return (void *) load_add_on(name);
}

/*
 * xmlModulePlatformClose:
 * beos api info: http://www.beunited.org/bebook/The%20Kernel%20Kit/Images.html
 * returns 0 on success, and non-zero on error.
 */

static int
xmlModulePlatformClose(void *handle)
{
    status_t rc;

    rc = unload_add_on((image_id) handle);

    if (rc == B_OK)
        return 0;
    else
        return -1;
}

/*
 * xmlModulePlatformSymbol:
 * beos api info: http://www.beunited.org/bebook/The%20Kernel%20Kit/Images.html
 * returns 0 on success and the loaded symbol in result, and -1 on error.
 */

static int
xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
{
    status_t rc;

    rc = get_image_symbol((image_id) handle, name, B_SYMBOL_TYPE_ANY, symbol);

    return (rc == B_OK) ? 0 : -1;
}

#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.
 */

static void *
xmlModulePlatformOpen(const char *name)
{
    char errbuf[256];
    void *handle;
    int rc;

    rc = DosLoadModule(errbuf, sizeof(errbuf) - 1, name, &handle);

    if (rc)
        return 0;
    else
        return (handle);
}

/*
 * xmlModulePlatformClose:
 * os2 api info: http://www.edm2.com/os2api/Dos/DosFreeModule.html
 * returns 0 on success, and non-zero on error.
 */

static int
xmlModulePlatformClose(void *handle)
{
    return DosFreeModule(handle);
}

/*
 * xmlModulePlatformSymbol:
 * os2 api info: http://www.edm2.com/os2api/Dos/DosQueryProcAddr.html
 * returns 0 on success and the loaded symbol in result, and -1 on error.
 */

static int
xmlModulePlatformSymbol(void *handle, const char *name, void **symbol)
{
    int rc;

    rc = DosQueryProcAddr(handle, 0, name, symbol);

    return (rc == NO_ERROR) ? 0 : -1;
}

#endif /* HAVE_OS2 */

#define bottom_xmlmodule
#include "elfgcchack.h"
#endif /* LIBXML_MODULES_ENABLED */

/* [<][>][^][v][top][bottom][index][help] */