Files
hdf5/src/H5PLint.c

395 lines
12 KiB
C
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* All rights reserved. *
* *
* This file is part of HDF5. The full HDF5 copyright notice, including *
* terms governing use, modification, and redistribution, is contained in *
* the COPYING file, which can be found at the root of the source code *
* distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Purpose: Internal routines for managing plugins.
*
*/
/****************/
/* Module Setup */
/****************/
#include "H5PLmodule.h" /* This source code file is part of the H5PL module */
/***********/
/* Headers */
/***********/
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
#include "H5MMprivate.h" /* Memory management */
#include "H5PLpkg.h" /* Plugin */
#include "H5Zprivate.h" /* Filter pipeline */
/****************/
/* Local Macros */
/****************/
/******************/
/* Local Typedefs */
/******************/
/********************/
/* Local Prototypes */
/********************/
/*********************/
/* Package Variables */
/*********************/
/* Package initialization variable */
hbool_t H5_PKG_INIT_VAR = FALSE;
/*****************************/
/* Library Private Variables */
/*****************************/
/*******************/
/* Local Variables */
/*******************/
/* Bitmask that controls whether classes of plugins
* (e.g.: filters, VOL drivers) can be loaded.
*/
static unsigned int H5PL_plugin_control_mask_g = H5PL_ALL_PLUGIN;
/* This flag will be set to FALSE if the HDF5_PLUGIN_PRELOAD
* environment variable was set to H5PL_NO_PLUGIN at
* package initialization.
*/
static hbool_t H5PL_allow_plugins_g = TRUE;
/*-------------------------------------------------------------------------
* Function: H5PL__get_plugin_control_mask
*
* Purpose: Gets the internal plugin control mask value.
*
* Return: SUCCEED/FAIL
*
*-------------------------------------------------------------------------
*/
herr_t
H5PL__get_plugin_control_mask(unsigned int *mask /*out*/)
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE_NOERR
/* Check args - Just assert on package functions */
HDassert(mask);
/* Return the mask */
*mask = H5PL_plugin_control_mask_g;
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5PL__get_plugin_control_mask() */
/*-------------------------------------------------------------------------
* Function: H5PL__set_plugin_control_mask
*
* Purpose: Sets the internal plugin control mask value.
*
* Return: SUCCEED/FAIL
*
*-------------------------------------------------------------------------
*/
herr_t
H5PL__set_plugin_control_mask(unsigned int mask)
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE_NOERR
/* Only allow setting this if plugins have not been disabled.
* XXX: Note that we don't consider this an error, but instead
* silently ignore it. We may want to consider this behavior
* more carefully.
*/
if (H5PL_allow_plugins_g)
H5PL_plugin_control_mask_g = mask;
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5PL__set_plugin_control_mask() */
/*-------------------------------------------------------------------------
* Function: H5PL__init_package
*
* Purpose: Initialize any package-specific data and call any init
* routines for the package.
*
* Return: SUCCEED/FAIL
*
*-------------------------------------------------------------------------
*/
herr_t
H5PL__init_package(void)
{
char *env_var = NULL;
herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE
/* Check the environment variable to determine if the user wants
* to ignore plugins. The special symbol H5PL_NO_PLUGIN (defined in
* H5PLpublic.h) means we don't want to load plugins.
*/
if (NULL != (env_var = HDgetenv("HDF5_PLUGIN_PRELOAD")))
if (!HDstrcmp(env_var, H5PL_NO_PLUGIN)) {
H5PL_plugin_control_mask_g = 0;
H5PL_allow_plugins_g = FALSE;
}
/* Create the table of previously-loaded plugins */
if (H5PL__create_plugin_cache() < 0)
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINIT, FAIL, "can't create plugin cache")
/* Create the table of search paths for dynamic libraries */
if (H5PL__create_path_table() < 0)
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINIT, FAIL, "can't create plugin search path table")
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5PL__init_package() */
/*-------------------------------------------------------------------------
* Function: H5PL_term_package
*
* Purpose: Terminate the H5PL interface: release all memory, reset all
* global variables to initial values. This only happens if all
* types have been destroyed from other interfaces.
*
* Return: Success: Positive if any action was taken that might
* affect some other interface; zero otherwise
* Failure: Negative
*
*-------------------------------------------------------------------------
*/
int
H5PL_term_package(void)
{
hbool_t already_closed = FALSE;
int ret_value = 0;
FUNC_ENTER_NOAPI_NOINIT
if (H5_PKG_INIT_VAR) {
/* Close the plugin cache.
* We need to bump the return value if we did any real work here.
*/
if (H5PL__close_plugin_cache(&already_closed) < 0)
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTFREE, (-1), "problem closing plugin cache")
if (!already_closed)
ret_value++;
/* Close the search path table and free the paths */
if (H5PL__close_path_table() < 0)
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTFREE, (-1), "problem closing search path table")
/* Mark the interface as uninitialized */
if (0 == ret_value)
H5_PKG_INIT_VAR = FALSE;
} /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5PL_term_package() */
/*-------------------------------------------------------------------------
* Function: H5PL_load
*
* Purpose: Given the plugin type and identifier, this function searches
* for and, if found, loads a dynamic plugin library.
*
* The function searches first in the cached plugins and then
* in the paths listed in the path table.
*
* Return: Success: A pointer to the plugin info
* Failure: NULL
*
*-------------------------------------------------------------------------
*/
const void *
H5PL_load(H5PL_type_t type, H5PL_key_t key)
{
H5PL_search_params_t search_params; /* Plugin search parameters */
hbool_t found = FALSE; /* Whether the plugin was found */
const void *plugin_info = NULL; /* Information from the plugin */
const void *ret_value = NULL;
FUNC_ENTER_NOAPI(NULL)
/* Check if plugins can be loaded for this plugin type */
switch (type) {
case H5PL_TYPE_FILTER:
if ((H5PL_plugin_control_mask_g & H5PL_FILTER_PLUGIN) == 0)
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTLOAD, NULL, "filter plugins disabled")
break;
case H5PL_TYPE_ERROR:
case H5PL_TYPE_NONE:
default:
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTLOAD, NULL, "Invalid plugin type specified")
}
/* Set up the search parameters */
search_params.type = type;
search_params.key.id = key.id;
/* Search in the table of already loaded plugin libraries */
if(H5PL__find_plugin_in_cache(&search_params, &found, &plugin_info) < 0)
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, NULL, "search in plugin cache failed")
/* If not found, try iterating through the path table to find an appropriate plugin */
if (!found)
if (H5PL__find_plugin_in_path_table(&search_params, &found, &plugin_info) < 0)
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, NULL, "search in path table failed")
/* Set the return value we found the plugin */
if (found)
ret_value = plugin_info;
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5PL_load() */
/*-------------------------------------------------------------------------
* Function: H5PL__open
*
* Purpose: Opens a plugin.
*
* The success parameter will be set to TRUE and the plugin_info
* parameter will be filled in on success. Otherwise, they
* will be FALSE and NULL, respectively.
*
* Return: SUCCEED/FAIL
*
*-------------------------------------------------------------------------
*/
/* NOTE: We turn off -Wpedantic in gcc to quiet a warning about converting
* object pointers to function pointers, which is undefined in ANSI C.
* This is basically unavoidable due to the nature of dlsym() and *is*
* defined in POSIX, so it's fine.
*
* This pragma only needs to surround the assignment of the
* get_plugin_info function pointer, but early (4.4.7, at least) gcc
* only allows diagnostic pragmas to be toggled outside of functions.
*/
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
herr_t
H5PL__open(const char *path, H5PL_type_t type, H5PL_key_t key, hbool_t *success, const void **plugin_info)
{
H5PL_HANDLE handle = NULL;
H5PL_get_plugin_info_t get_plugin_info = NULL;
herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE
/* Check args - Just assert on package functions */
HDassert(path);
HDassert(success);
HDassert(plugin_info);
/* Initialize out parameters */
*success = FALSE;
*plugin_info = NULL;
/* There are different reasons why a library can't be open, e.g. wrong architecture.
* If we can't open the library, just return.
*/
if (NULL == (handle = H5PL_OPEN_DLIB(path))) {
H5PL_CLR_ERROR; /* clear error */
HGOTO_DONE(SUCCEED)
}
/* Return a handle for the function H5PLget_plugin_info in the dynamic library.
* The plugin library is suppose to define this function.
*/
if (NULL == (get_plugin_info = (H5PL_get_plugin_info_t)H5PL_GET_LIB_FUNC(handle, "H5PLget_plugin_info")))
HGOTO_DONE(SUCCEED)
/* Get the plugin information */
switch (type) {
case H5PL_TYPE_FILTER:
{
const H5Z_class2_t *filter_info;
/* Get the plugin info */
if (NULL == (filter_info = (const H5Z_class2_t *)(*get_plugin_info)()))
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "can't get filter info from plugin")
/* If the filter IDs match, we're done. Set the output parameters. */
if (filter_info->id == key.id) {
*plugin_info = (const void *)filter_info;
*success = TRUE;
}
break;
}
case H5PL_TYPE_ERROR:
case H5PL_TYPE_NONE:
default:
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "Invalid plugin type specified")
} /* end switch */
/* If we found the correct plugin, store it in the cache */
if (*success)
if (H5PL__add_plugin(type, key, handle))
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINSERT, FAIL, "unable to add new plugin to plugin cache")
done:
if (!(*success) && handle)
if (H5PL__close(handle) < 0)
HDONE_ERROR(H5E_PLUGIN, H5E_CLOSEERROR, FAIL, "can't close dynamic library")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5PL__open() */
#pragma GCC diagnostic pop
/*-------------------------------------------------------------------------
* Function: H5PL__close
*
* Purpose: Closes the handle for dynamic library
*
* Return: SUCCEED/FAIL
*
*-------------------------------------------------------------------------
*/
herr_t
H5PL__close(H5PL_HANDLE handle)
{
FUNC_ENTER_PACKAGE_NOERR
H5PL_CLOSE_LIB(handle);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5PL__close() */