summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5PL.c94
1 files changed, 87 insertions, 7 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);