diff options
Diffstat (limited to 'src/H5Lexternal.c')
-rw-r--r-- | src/H5Lexternal.c | 280 |
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 * |