summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5PL.c94
-rw-r--r--test/CMakeTests.cmake6
-rw-r--r--test/test_plugin.sh.in33
3 files changed, 114 insertions, 19 deletions
diff --git a/src/H5PL.c b/src/H5PL.c
index 3eb3392..2789a5e 100644
--- a/src/H5PL.c
+++ b/src/H5PL.c
@@ -122,6 +122,15 @@ typedef const void *(*H5PL_get_plugin_info_t)(void);
/* Special symbol to indicate no plugin loading */
#define H5PL_NO_PLUGIN "::"
+/* Special symbol to indicate relative path from environment */
+/* Restrict usage of special char only for the default path H5_DEFAULT_PLUGINDIR
+ * or when using the environment variable HDF5_PLUGIN_PATH */
+#define H5PL_PLUGIN_ENV_RELEXEC_CHAR '@'
+
+/* Maximum size for path to executable */
+#ifndef MAX_EXEC_PATH
+#define MAX_EXEC_PATH 2048
+#endif
/******************/
/* Local Typedefs */
@@ -139,6 +148,7 @@ typedef struct H5PL_table_t {
/* Local Prototypes */
/********************/
+static char *H5PL__env_strdup(const char *plpath);
static herr_t H5PL__init_path_table(void);
static htri_t H5PL__find(H5PL_type_t plugin_type, int type_id, char *dir, const void **info);
static htri_t H5PL__open(H5PL_type_t pl_type, char *libname, int plugin_id, const void **pl_info);
@@ -172,6 +182,7 @@ static H5PL_table_t *H5PL_table_g = NULL;
static char *H5PL_path_table_g[H5PL_MAX_PATH_NUM];
static size_t H5PL_num_paths_g = 0;
static hbool_t H5PL_path_found_g = FALSE;
+static char *H5PL_executable_path_g = NULL;
/* Enable all plugin libraries */
static unsigned int H5PL_plugin_g = H5PL_ALL_PLUGIN;
@@ -192,19 +203,54 @@ DESCRIPTION
herr_t
H5PL__init_package(void)
{
- char *preload_path;
+ herr_t ret_value = SUCCEED; /* Return value */
+ char *preload_path = NULL;
+ char *tempbuf = NULL;
+ char pathsep = '/';
+ char *bs = NULL;
+ size_t ncopy = MAX_EXEC_PATH;
- FUNC_ENTER_PACKAGE_NOERR
+ FUNC_ENTER_PACKAGE
/* Retrieve pathnames from HDF5_PLUGIN_PRELOAD if the user sets it
* to tell the library to load plugin libraries without search.
*/
if(NULL != (preload_path = HDgetenv("HDF5_PLUGIN_PRELOAD")))
- /* Special symbal "::" means no plugin during data reading. */
+ /* Special symbol "::" means no plugin during data reading. */
if(!HDstrcmp(preload_path, H5PL_NO_PLUGIN))
H5PL_plugin_g = 0;
- FUNC_LEAVE_NOAPI(SUCCEED)
+ /* Retrieve the executable path for use with H5PL_PLUGIN_ENV_RELEXEC_CHAR
+ * if the user uses it in a plugin path.
+ */
+ if(NULL == (tempbuf = (char *)H5MM_malloc(MAX_EXEC_PATH)))
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for executable path")
+#if defined(_WIN32) || defined(_WIN64) || defined(H5_HAVE_WIN32_API)
+ pathsep = (char)'\\';
+ GetModuleFileName(NULL, tempbuf, MAX_EXEC_PATH);
+#elif defined(__APPLE__)
+ pathsep = (char)'/';
+ {
+ uint32_t size = sizeof(tempbuf);
+ _NSGetExecutablePath(tempbuf, &size);
+ }
+#else
+ pathsep = (char)'/';
+ {
+ ssize_t count = readlink("/proc/self/exe", tempbuf, MAX_EXEC_PATH);
+ tempbuf[count] = '\0';
+ }
+#endif
+ if ((bs = HDstrrchr(tempbuf, pathsep)))
+ ncopy = (size_t)(bs - tempbuf);
+ tempbuf[ncopy] = '\0';
+
+ H5PL_executable_path_g = H5MM_strdup(tempbuf);
+ if(tempbuf)
+ tempbuf = (char *)H5MM_xfree(tempbuf);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5PL__init_package() */
@@ -257,6 +303,10 @@ H5PL_term_package(void)
n++;
} /* end if */
+ /* Free the executable path */
+ if(H5PL_executable_path_g)
+ H5PL_executable_path_g = (char *)H5MM_xfree(H5PL_executable_path_g);
+
/* Mark the interface as uninitialized */
if(0 == n)
H5_PKG_INIT_VAR = FALSE;
@@ -265,6 +315,36 @@ H5PL_term_package(void)
FUNC_LEAVE_NOAPI(n)
} /* end H5PL_term_package() */
+static char*
+H5PL__env_strdup(const char *plpath)
+{
+ char *ret_value = NULL;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == plpath)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, NULL, "no path provided")
+ if (*plpath == H5PL_PLUGIN_ENV_RELEXEC_CHAR) {
+ char *tempbuf;
+ size_t ExecPathLength = HDstrlen(H5PL_executable_path_g);
+ size_t PluginPathLength = HDstrlen(plpath);
+
+ if(NULL == (tempbuf = (char *)H5MM_malloc(ExecPathLength + PluginPathLength)))
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, NULL, "can't allocate memory for plugin path")
+
+ HDstrncpy(tempbuf, H5PL_executable_path_g, ExecPathLength);
+ HDstrncpy(tempbuf+ExecPathLength, plpath+1, PluginPathLength-1);
+ tempbuf[ExecPathLength + PluginPathLength] = '\0';
+ ret_value = H5MM_strdup(tempbuf);
+ tempbuf = (char *)H5MM_xfree(tempbuf);
+ }
+ else
+ ret_value = H5MM_strdup(plpath);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL_env_strdup() */
+
/*-------------------------------------------------------------------------
* Function: H5PLset_loading_state
@@ -609,7 +689,7 @@ ssize_t
H5PLget(unsigned int index, char *pathname/*out*/, size_t size)
{
ssize_t ret_value = 0; /* Return value */
- ssize_t len = 0; /* Length of pathname */
+ size_t len = 0; /* Length of pathname */
char *dl_path = NULL;
FUNC_ENTER_API(FAIL)
@@ -628,7 +708,7 @@ H5PLget(unsigned int index, char *pathname/*out*/, size_t size)
} /* end if */
/* Set return value */
- ret_value = len;
+ ret_value = (ssize_t)len;
done:
FUNC_LEAVE_API(ret_value)
@@ -698,7 +778,7 @@ H5PL__init_path_table(void)
/* Check for too many directories in path */
if(H5PL_num_paths_g == H5PL_MAX_PATH_NUM)
HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "too many directories in path for table")
- if(NULL == (H5PL_path_table_g[H5PL_num_paths_g] = H5MM_strdup(dir)))
+ if(NULL == (H5PL_path_table_g[H5PL_num_paths_g] = H5PL__env_strdup(dir)))
HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path")
H5PL_num_paths_g++;
dir = HDstrtok(NULL, H5PL_PATH_SEPARATOR);
diff --git a/test/CMakeTests.cmake b/test/CMakeTests.cmake
index cbab6fe..86c5cb3 100644
--- a/test/CMakeTests.cmake
+++ b/test/CMakeTests.cmake
@@ -996,6 +996,12 @@ set_tests_properties (H5PLUGIN-plugin PROPERTIES
WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}
)
+add_test (NAME H5PLUGIN-pluginRelative COMMAND $<TARGET_FILE:plugin>)
+set_tests_properties (H5PLUGIN-pluginRelative PROPERTIES
+ ENVIRONMENT "HDF5_PLUGIN_PATH=@/../testdir1${CMAKE_SEP}@/../testdir2;srcdir=${HDF5_TEST_BINARY_DIR}"
+ WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}
+)
+
##############################################################################
### S W M R T E S T S
##############################################################################
diff --git a/test/test_plugin.sh.in b/test/test_plugin.sh.in
index 1cd87e3..1e6d9d9 100644
--- a/test/test_plugin.sh.in
+++ b/test/test_plugin.sh.in
@@ -1,16 +1,16 @@
#! /bin/sh
#
-# 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 files COPYING and Copyright.html. COPYING can be found at the root
-# of the source code distribution tree; Copyright.html can be found at the
-# root level of an installed copy of the electronic document set and is
-# linked from the top-level documents page. It can also be found at
-# http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have access
-# to either file, you may request a copy from help@hdfgroup.org.
+# 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 files COPYING and Copyright.html. COPYING can be found at the root
+# of the source code distribution tree; Copyright.html can be found at the
+# root level of an installed copy of the electronic document set and is
+# linked from the top-level documents page. It can also be found at
+# http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have access
+# to either file, you may request a copy from help@hdfgroup.org.
#
srcdir=@srcdir@
TOP_BUILDDIR=@top_builddir@
@@ -40,7 +40,7 @@ case $(uname) in
esac
PLUGIN_LIBDIR1=testdir1
PLUGIN_LIBDIR2=testdir2
-CP="cp -p" # Use -p to preserve mode,ownership,timestamps
+CP="cp -p" # Use -p to preserve mode,ownership,timestamps
RM="rm -rf"
# Print a line-line message left justified in a field of 70 characters
@@ -87,6 +87,15 @@ if [ $? != 0 ]; then
nerrors=`expr $nerrors + 1`
fi
+# setup plugin path relative to test
+ENVCMD="env HDF5_PLUGIN_PATH=@/${PLUGIN_LIBDIR1}:@/${PLUGIN_LIBDIR2}"
+
+# Run the test
+$ENVCMD $TEST_BIN
+if [ $? != 0 ]; then
+ nerrors=`expr $nerrors + 1`
+fi
+
# print results
if test $nerrors -ne 0 ; then
echo "$nerrors errors encountered"