summaryrefslogtreecommitdiffstats
path: root/src/H5Lexternal.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Lexternal.c')
-rw-r--r--src/H5Lexternal.c280
1 files changed, 35 insertions, 245 deletions
diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c
index 6c132ab..73ca17c 100644
--- a/src/H5Lexternal.c
+++ b/src/H5Lexternal.c
@@ -15,7 +15,7 @@
/* Module Setup */
/****************/
-#define H5G_FRIEND /*suppress error about including H5Gpkg */
+#define H5G_FRIEND /*suppress error about including H5Gpkg */
#include "H5Lmodule.h" /* This source code file is part of the H5L module */
@@ -26,8 +26,9 @@
#include "H5ACprivate.h" /* Metadata cache */
#include "H5CXprivate.h" /* API Contexts */
#include "H5Eprivate.h" /* Error handling */
+#include "H5Fprivate.h" /* Files */
#include "H5Gpkg.h" /* Groups */
-#include "H5Iprivate.h" /* IDs */
+#include "H5Iprivate.h" /* IDs */
#include "H5Lpkg.h" /* Links */
#include "H5MMprivate.h" /* Memory management */
#include "H5Opublic.h" /* File objects */
@@ -56,9 +57,6 @@
/********************/
/* Local Prototypes */
/********************/
-static char *H5L__getenv_prefix_name(char **env_prefix/*in,out*/);
-static herr_t H5L__build_name(const char *prefix, const char *file_name,
- char **full_name/*out*/);
static hid_t H5L__extern_traverse(const char *link_name, hid_t cur_group,
const void *udata, size_t udata_size, hid_t lapl_id, hid_t dxpl_id);
static ssize_t H5L__extern_query(const char *link_name, const void *udata,
@@ -82,7 +80,7 @@ static ssize_t H5L__extern_query(const char *link_name, const void *udata,
/* Default External Link link class */
static const H5L_class_t H5L_EXTERN_LINK_CLASS[1] = {{
H5L_LINK_CLASS_T_VERS, /* H5L_class_t version */
- H5L_TYPE_EXTERNAL, /* Link type id number */
+ H5L_TYPE_EXTERNAL, /* Link type id number */
"external", /* Link name for debugging */
NULL, /* Creation callback */
NULL, /* Move callback */
@@ -92,83 +90,10 @@ static const H5L_class_t H5L_EXTERN_LINK_CLASS[1] = {{
H5L__extern_query /* Query callback */
}};
-
-
-/*--------------------------------------------------------------------------
- * Function: H5L__getenv_prefix_name
- *
- * Purpose: Get the first pathname in the list of pathnames stored in ENV_PREFIX,
- * which is separated by the environment delimiter.
- * ENV_PREFIX is modified to point to the remaining pathnames
- * in the list.
- *
- * Return: A pointer to a pathname
- *
- * Programmer: Vailin Choi, April 2, 2008
- *
---------------------------------------------------------------------------*/
-static char *
-H5L__getenv_prefix_name(char **env_prefix/*in,out*/)
-{
- char *retptr = NULL;
- char *strret = NULL;
-
- FUNC_ENTER_STATIC_NOERR
-
- strret = HDstrchr(*env_prefix, H5_COLON_SEPC);
- if(strret == NULL) {
- retptr = *env_prefix;
- *env_prefix = strret;
- } /* end if */
- else {
- retptr = *env_prefix;
- *env_prefix = strret + 1;
- *strret = '\0';
- } /* end else */
-
- FUNC_LEAVE_NOAPI(retptr)
-} /* end H5L__getenv_prefix_name() */
-
-
-/*--------------------------------------------------------------------------
- * Function: H5L__build_name
- *
- * Purpose: Prepend PREFIX to FILE_NAME and store in FULL_NAME
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Vailin Choi, April 2, 2008
- *
---------------------------------------------------------------------------*/
-static herr_t
-H5L__build_name(const char *prefix, const char *file_name, char **full_name/*out*/)
-{
- size_t prefix_len; /* length of prefix */
- size_t fname_len; /* Length of external link file name */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_STATIC
-
- prefix_len = HDstrlen(prefix);
- fname_len = HDstrlen(file_name);
-
- /* Allocate a buffer to hold the filename + prefix + possibly the delimiter + terminating null byte */
- if(NULL == (*full_name = (char *)H5MM_malloc(prefix_len + fname_len + 2)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate filename buffer")
-
- /* Compose the full file name */
- HDsnprintf(*full_name, (prefix_len + fname_len + 2), "%s%s%s", prefix,
- (H5_CHECK_DELIMITER(prefix[prefix_len - 1]) ? "" : H5_DIR_SEPS), file_name);
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5L__build_name() */
-
-
/*-------------------------------------------------------------------------
* Function: H5L__extern_traverse
*
- * Purpose: Default traversal function for external links. This can
+ * Purpose: Default traversal function for external links. This can
* be overridden using H5Lregister().
*
* Given a filename and path packed into the link udata,
@@ -177,9 +102,9 @@ done:
* link access property list, appends that prefix to the
* filename being opened.
*
- * Return: ID of the opened object on success/Negative on failure
+ * Return: ID of the opened object on success/Negative on failure
*
- * Programmer: James Laird
+ * Programmer: James Laird
* Monday, July 10, 2006
*
*-------------------------------------------------------------------------
@@ -190,13 +115,11 @@ H5L__extern_traverse(const char H5_ATTR_UNUSED *link_name, hid_t cur_group,
hid_t H5_ATTR_UNUSED dxpl_id)
{
H5P_genplist_t *plist; /* Property list pointer */
- char *my_prefix; /* Library's copy of the prefix */
H5G_loc_t root_loc; /* Location of root group in external file */
H5G_loc_t loc; /* Location of object */
- H5F_t *ext_file = NULL; /* File struct for external file */
+ H5F_t *ext_file = NULL; /* File struct for external file */
const uint8_t *p = (const uint8_t *)_udata; /* Pointer into external link buffer */
const char *file_name; /* Name of file containing external link's object */
- char *full_name = NULL; /* File name with prefix */
const char *obj_name; /* Name external link's object */
size_t fname_len; /* Length of external link file name */
unsigned intent; /* File access permissions */
@@ -205,11 +128,9 @@ H5L__extern_traverse(const char H5_ATTR_UNUSED *link_name, hid_t cur_group,
hid_t ext_obj = -1; /* ID for external link's object */
char *parent_group_name = NULL;/* Temporary pointer to group name */
char local_group_name[H5L_EXT_TRAVERSE_BUF_SIZE]; /* Local buffer to hold group name */
- char *temp_file_name = NULL; /* Temporary pointer to file name */
- size_t temp_file_name_len; /* Length of temporary file name */
- char *actual_file_name = NULL; /* Parent file's actual name */
H5P_genplist_t *fa_plist; /* File access property list pointer */
H5F_close_degree_t fc_degree = H5F_CLOSE_WEAK; /* File close degree for target file */
+ char *elink_prefix; /* Pointer to elink prefix */
hid_t ret_value = H5I_INVALID_HID; /* Return value */
FUNC_ENTER_STATIC
@@ -251,7 +172,7 @@ H5L__extern_traverse(const char H5_ATTR_UNUSED *link_name, hid_t cur_group,
intent = H5F_INTENT(loc.oloc->file);
if((fapl_id == H5P_DEFAULT) && ((fapl_id = H5F_get_access_plist(loc.oloc->file, FALSE)) < 0))
- HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get parent's file access property list")
+ HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get parent's file access property list")
/* Get callback_info */
if(H5P_get(plist, H5L_ACS_ELINK_CB_NAME, &cb_info) < 0)
@@ -259,7 +180,7 @@ H5L__extern_traverse(const char H5_ATTR_UNUSED *link_name, hid_t cur_group,
/* Get file access property list */
if(NULL == (fa_plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
/* Make callback if it exists */
if(cb_info.func) {
@@ -299,142 +220,15 @@ H5L__extern_traverse(const char H5_ATTR_UNUSED *link_name, hid_t cur_group,
/* Set file close degree for new file to "weak" */
if(H5P_set(fa_plist, H5F_ACS_CLOSE_DEGREE_NAME, &fc_degree) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file close degree")
-
- /*
- * Start searching for the target file
- */
-
- /* Simplify intent flags for open calls */
- intent &= (H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE | H5F_ACC_SWMR_READ);
-
- /* Copy the file name to use */
- if(NULL == (temp_file_name = H5MM_strdup(file_name)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- temp_file_name_len = HDstrlen(temp_file_name);
-
- /* target file_name is an absolute pathname: see RM for detailed description */
- if(H5_CHECK_ABSOLUTE(file_name) || H5_CHECK_ABS_PATH(file_name)) {
- /* Try opening file */
- if(NULL == (ext_file = H5F_efc_open(loc.oloc->file, file_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id))) {
- char *ptr;
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file close degree")
- H5E_clear_stack(NULL);
+ /* Get the current elink prefix */
+ if(H5P_peek(plist, H5L_ACS_ELINK_PREFIX_NAME, &elink_prefix) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external link prefix")
- /* get last component of file_name */
- H5_GET_LAST_DELIMITER(file_name, ptr)
- HDassert(ptr);
-
- /* Increment past delimiter */
- ptr++;
-
- /* Copy into the temp. file name */
- HDstrncpy(temp_file_name, ptr, temp_file_name_len);
- temp_file_name[temp_file_name_len - 1] = '\0';
- } /* end if */
- } /* end if */
- else if(H5_CHECK_ABS_DRIVE(file_name)) {
- /* Try opening file */
- if(NULL == (ext_file = H5F_efc_open(loc.oloc->file, file_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id))) {
-
- H5E_clear_stack(NULL);
-
- /* strip "<drive-letter>:" */
- HDstrncpy(temp_file_name, &file_name[2], temp_file_name_len);
- temp_file_name[temp_file_name_len - 1] = '\0';
- } /* end if */
- } /* end if */
-
- /* try searching from paths set in the environment variable */
- if(ext_file == NULL) {
- char *env_prefix;
-
- if(NULL != (env_prefix = HDgetenv("HDF5_EXT_PREFIX"))) {
- char *tmp_env_prefix, *saved_env;
-
- if(NULL == (saved_env = tmp_env_prefix = H5MM_strdup(env_prefix)))
- HGOTO_ERROR(H5E_LINK, H5E_NOSPACE, FAIL, "memory allocation failed")
-
- while((tmp_env_prefix) && (*tmp_env_prefix)) {
- char *out_prefix_name;
-
- out_prefix_name = H5L__getenv_prefix_name(&tmp_env_prefix/*in,out*/);
- if(out_prefix_name && (*out_prefix_name)) {
- if(H5L__build_name(out_prefix_name, temp_file_name, &full_name/*out*/) < 0) {
- saved_env = (char *)H5MM_xfree(saved_env);
- HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't prepend prefix to filename")
- } /* end if */
-
- ext_file = H5F_efc_open(loc.oloc->file, full_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id);
- full_name = (char *)H5MM_xfree(full_name);
- if(ext_file != NULL)
- break;
- H5E_clear_stack(NULL);
- } /* end if */
- } /* end while */
- saved_env = (char *)H5MM_xfree(saved_env);
- } /* end if */
- } /* end if */
-
- /* try searching from property list */
- if(ext_file == NULL) {
- if(H5P_peek(plist, H5L_ACS_ELINK_PREFIX_NAME, &my_prefix) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external link prefix")
- if(my_prefix) {
- if(H5L__build_name(my_prefix, temp_file_name, &full_name/*out*/) < 0)
- HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't prepend prefix to filename")
- if(NULL == (ext_file = H5F_efc_open(loc.oloc->file, full_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id)))
- H5E_clear_stack(NULL);
- full_name = (char *)H5MM_xfree(full_name);
- } /* end if */
- } /* end if */
-
- /* try searching from main file's "extpath": see description in H5F_open() & H5_build_extpath() */
- if(ext_file == NULL) {
- char *extpath;
-
- if(NULL != (extpath = H5F_EXTPATH(loc.oloc->file))) {
- if(H5L__build_name(extpath, temp_file_name, &full_name/*out*/) < 0)
- HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't prepend prefix to filename")
- if(NULL == (ext_file = H5F_efc_open(loc.oloc->file, full_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id)))
- H5E_clear_stack(NULL);
- full_name = (char *)H5MM_xfree(full_name);
- } /* end if */
- } /* end if */
-
- /* try the relative file_name stored in temp_file_name */
- if(ext_file == NULL) {
- if(NULL == (ext_file = H5F_efc_open(loc.oloc->file, temp_file_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id)))
- H5E_clear_stack(NULL);
- } /* end if */
-
- /* try the 'resolved' name for the parent file (i.e. the name after symlinks
- * were resolved)
- */
- if(ext_file == NULL) {
- char *ptr = NULL;
-
- /* Copy resolved file name */
- if(NULL == (actual_file_name = H5MM_strdup(H5F_ACTUAL_NAME(loc.oloc->file))))
- HGOTO_ERROR(H5E_LINK, H5E_CANTALLOC, FAIL, "can't duplicate resolved file name string")
-
- /* get last component of file_name */
- H5_GET_LAST_DELIMITER(actual_file_name, ptr)
- if(!ptr)
- HGOTO_ERROR(H5E_LINK, H5E_CANTOPENFILE, FAIL, "unable to open external file, external link file name = '%s', temp_file_name = '%s'", file_name, temp_file_name)
-
- /* Truncate filename portion from actual file name path */
- *ptr = '\0';
-
- /* Build new file name for the external file */
- if(H5L__build_name(actual_file_name, temp_file_name, &full_name/*out*/) < 0)
- HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't prepend prefix to filename")
-
- /* Try opening with the resolved name */
- if(NULL == (ext_file = H5F_efc_open(loc.oloc->file, full_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id)))
- HGOTO_ERROR(H5E_LINK, H5E_CANTOPENFILE, FAIL, "unable to open external file, external link file name = '%s', temp_file_name = '%s'", file_name, temp_file_name)
- full_name = (char *)H5MM_xfree(full_name);
- } /* end if */
+ /* Search for the target file */
+ if(NULL == (ext_file = H5F_prefix_open_file(loc.oloc->file, H5F_PREFIX_ELINK, elink_prefix, file_name, intent, fapl_id)))
+ HGOTO_ERROR(H5E_LINK, H5E_CANTOPENFILE, FAIL, "unable to open external file, external link file name = '%s'", file_name)
/* Retrieve the "group location" for the file's root group */
if(H5G_root_loc(ext_file, &root_loc) < 0)
@@ -455,10 +249,6 @@ done:
HDONE_ERROR(H5E_LINK, H5E_CANTCLOSEFILE, FAIL, "problem closing external file")
if(parent_group_name && parent_group_name != local_group_name)
parent_group_name = (char *)H5MM_xfree(parent_group_name);
- full_name = (char *)H5MM_xfree(full_name);
- temp_file_name = (char *)H5MM_xfree(temp_file_name);
- actual_file_name = (char *)H5MM_xfree(actual_file_name);
-
if(ret_value < 0) {
/* Close object if it's open and something failed */
if(ext_obj >= 0 && H5I_dec_ref(ext_obj) < 0)
@@ -468,20 +258,20 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5L__extern_traverse() */
-
+
/*-------------------------------------------------------------------------
* Function: H5L__extern_query
*
- * Purpose: Default query function for external links. This can
+ * Purpose: Default query function for external links. This can
* be overridden using H5Lregister().
*
* Returns the size of the link's user data. If a buffer of
* is provided, copies at most buf_size bytes of the udata
* into it.
*
- * Return: Size of buffer on success/Negative on failure
+ * Return: Size of buffer on success/Negative on failure
*
- * Programmer: James Laird
+ * Programmer: James Laird
* Monday, July 10, 2006
*
*-------------------------------------------------------------------------
@@ -518,23 +308,23 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5L__extern_query() */
-
+
/*-------------------------------------------------------------------------
- * Function: H5Lcreate_external
+ * Function: H5Lcreate_external
*
- * Purpose: Creates an external link from LINK_NAME to OBJ_NAME.
+ * Purpose: Creates an external link from LINK_NAME to OBJ_NAME.
*
* External links are links to objects in other HDF5 files. They
* are allowed to "dangle" like soft links internal to a file.
* FILE_NAME is the name of the file that OBJ_NAME is is contained
* within. If OBJ_NAME is given as a relative path name, the
* path will be relative to the root group of FILE_NAME.
- * LINK_NAME is interpreted relative to LINK_LOC_ID, which is
+ * LINK_NAME is interpreted relative to LINK_LOC_ID, which is
* either a file ID or a group ID.
*
- * Return: Non-negative on success/Negative on failure
+ * Return: Non-negative on success/Negative on failure
*
- * Programmer: Quincey Koziol
+ * Programmer: Quincey Koziol
* Wednesday, May 18, 2005
*
*-------------------------------------------------------------------------
@@ -543,8 +333,8 @@ herr_t
H5Lcreate_external(const char *file_name, const char *obj_name,
hid_t link_loc_id, const char *link_name, hid_t lcpl_id, hid_t lapl_id)
{
- H5G_loc_t link_loc; /* Group location to create link */
- char *norm_obj_name = NULL; /* Pointer to normalized current name */
+ H5G_loc_t link_loc; /* Group location to create link */
+ char *norm_obj_name = NULL; /* Pointer to normalized current name */
void *ext_link_buf = NULL; /* Buffer to contain external link */
size_t buf_size; /* Size of buffer to hold external link */
size_t file_name_len; /* Length of file name string */
@@ -559,13 +349,13 @@ hbool_t api_ctx_pushed = FALSE; /* Whether API context pushed */
/* Check arguments */
if(!file_name || !*file_name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no file name specified")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no file name specified")
if(!obj_name || !*obj_name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name specified")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name specified")
if(H5G_loc(link_loc_id, &link_loc) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
if(!link_name || !*link_name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no link name specified")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no link name specified")
/* Get normalized copy of the link target */
if(NULL == (norm_obj_name = H5G_normalize(obj_name)))
@@ -606,7 +396,7 @@ if(api_ctx_pushed && H5CX_pop() < 0)
FUNC_LEAVE_API(ret_value)
} /* end H5Lcreate_external() */
-
+
/*-------------------------------------------------------------------------
* Function: H5L_register_external
*
@@ -635,7 +425,7 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5L_register_external() */
-
+
/*-------------------------------------------------------------------------
* Function: H5Lunpack_elink_val
*