diff options
Diffstat (limited to 'src/H5Fint.c')
-rw-r--r-- | src/H5Fint.c | 327 |
1 files changed, 293 insertions, 34 deletions
diff --git a/src/H5Fint.c b/src/H5Fint.c index 79f0d06..9d79481 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -30,6 +30,7 @@ #include "H5FDprivate.h" /* File drivers */ #include "H5Gprivate.h" /* Groups */ #include "H5Iprivate.h" /* IDs */ +#include "H5Lprivate.h" /* Links */ #include "H5MFprivate.h" /* File memory management */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ @@ -98,7 +99,7 @@ H5FL_DEFINE(H5F_t); /* Declare a free list to manage the H5F_file_t struct */ H5FL_DEFINE(H5F_file_t); - + /*------------------------------------------------------------------------- * Function: H5F_get_access_plist * @@ -213,7 +214,7 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_get_access_plist() */ - + /*------------------------------------------------------------------------- * Function: H5F_get_obj_count * @@ -241,7 +242,7 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_get_obj_count() */ - + /*------------------------------------------------------------------------- * Function: H5F_get_obj_ids * @@ -268,7 +269,7 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_get_obj_ids() */ - + /*--------------------------------------------------------------------------- * Function: H5F_get_objects * @@ -370,7 +371,7 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_get_objects() */ - + /*------------------------------------------------------------------------- * Function: H5F_get_objects_cb * @@ -479,7 +480,265 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_get_objects_cb() */ - +/*-------------------------------------------------------------------------- + * Function: H5F__build_name + * + * Purpose: Prepend PREFIX to FILE_NAME and store in FULL_NAME + * + * Return: Non-negative on success/Negative on failure + *--------------------------------------------------------------------------*/ +static herr_t +H5F__build_name(char *prefix, 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) +} /* H5F__build_name() */ + + +/*-------------------------------------------------------------------------- + * Function: H5F__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 +--------------------------------------------------------------------------*/ +static char * +H5F__getenv_prefix_name(char **env_prefix/*in,out*/) +{ + char *retptr=NULL; + char *strret=NULL; + + FUNC_ENTER_STATIC + + strret = HDstrchr(*env_prefix, H5_COLON_SEPC); + if (strret == NULL) { + retptr = *env_prefix; + *env_prefix = strret; + } else { + retptr = *env_prefix; + *env_prefix = strret + 1; + *strret = '\0'; + } + + FUNC_LEAVE_NOAPI(retptr) +} /* end H5F__getenv_prefix_name() */ + +/*------------------------------------------------------------------------- + * Function: H5F_prefix_open_file + * + * Purpose: Attempts to open a dataset file. + * + * Return: Non-negative on success/Negative on failure + *------------------------------------------------------------------------- + */ +H5F_t * +H5F_prefix_open_file(hid_t plist_id, H5F_t *primary_file, const char *prefix_type, + const char *file_name, unsigned file_intent, hid_t fapl_id, hid_t dxpl_id) +{ + H5F_t *src_file = NULL; /* Source file */ + H5F_t *ret_value = NULL; /* Actual return value */ + char *full_name = NULL; /* File name with prefix */ + char *my_prefix = NULL; /* Library's copy of the prefix */ + char *actual_file_name = NULL; /* File's actual name */ + char *temp_file_name = NULL; /* Temporary pointer to file name */ + size_t temp_file_name_len; /* Length of temporary file name */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Simplify intent flags for open calls */ + file_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, NULL, "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 == (src_file = H5F_efc_open(primary_file, file_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id, dxpl_id))) { + char *ptr; + + H5E_clear_stack(NULL); + + /* 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 == (src_file = H5F_efc_open(primary_file, file_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id, dxpl_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(src_file == NULL) { + char *env_prefix; + + if (HDstrcmp(prefix_type, H5D_ACS_VDS_PREFIX_NAME) == 0) + env_prefix = HDgetenv("HDF5_VDS_PREFIX"); + else if (HDstrcmp(prefix_type, H5L_ACS_ELINK_PREFIX_NAME) == 0) + env_prefix = HDgetenv("HDF5_EXT_PREFIX"); + else + HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, NULL, "prefix name is not sensible") + if(NULL != env_prefix) { + char *tmp_env_prefix, *saved_env; + + if(NULL == (saved_env = tmp_env_prefix = H5MM_strdup(env_prefix))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + + while((tmp_env_prefix) && (*tmp_env_prefix)) { + char *out_prefix_name; + + out_prefix_name = H5F__getenv_prefix_name(&tmp_env_prefix/*in,out*/); + if(out_prefix_name && (*out_prefix_name)) { + if(H5F__build_name(out_prefix_name, temp_file_name, &full_name/*out*/) < 0) { + saved_env = (char *)H5MM_xfree(saved_env); + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't prepend prefix to filename") + } /* end if */ + + src_file = H5F_efc_open(primary_file, full_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id, dxpl_id); + full_name = (char *)H5MM_xfree(full_name); + if(src_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(src_file == NULL) { + ssize_t size = 0; + H5E_BEGIN_TRY { + if (HDstrcmp(prefix_type, H5D_ACS_VDS_PREFIX_NAME) == 0) + size = H5Pget_virtual_prefix(plist_id, NULL, 0); + else if (HDstrcmp(prefix_type, H5L_ACS_ELINK_PREFIX_NAME) == 0) + size = H5Pget_elink_prefix(plist_id, NULL, 0); + } H5E_END_TRY; + if(size <= 0) + my_prefix = NULL; + else { + /* Allocate a buffer to hold the filename + prefix + possibly the delimiter + terminating null byte */ + if(NULL == (my_prefix = (char *)H5MM_malloc((size_t)size + 1))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate prefix buffer") + if (HDstrcmp(prefix_type, H5D_ACS_VDS_PREFIX_NAME) == 0) + size = H5Pget_virtual_prefix(plist_id, my_prefix, (size_t)size+1); + else if (HDstrcmp(prefix_type, H5L_ACS_ELINK_PREFIX_NAME) == 0) + size = H5Pget_elink_prefix(plist_id, my_prefix, (size_t)size+1); + if(size < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get file prefix") + if(my_prefix) { + if(H5F__build_name(my_prefix, temp_file_name, &full_name/*out*/) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't prepend prefix to filename") + my_prefix = (char *)H5MM_xfree(my_prefix); + if(NULL == (src_file = H5F_efc_open(primary_file, full_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id, dxpl_id))) + H5E_clear_stack(NULL); + full_name = (char *)H5MM_xfree(full_name); + } + } + } + + /* try searching from main file's "extpath": see description in H5F_open() & H5_build_extpath() */ + if(src_file == NULL) { + char *dspath; + + if(NULL != (dspath = H5F_EXTPATH(primary_file))) { + if(H5F__build_name(dspath, temp_file_name, &full_name/*out*/) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't prepend prefix to filename") + if(NULL == (src_file = H5F_efc_open(primary_file, full_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id, dxpl_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(src_file == NULL) { + if(NULL == (src_file = H5F_efc_open(primary_file, temp_file_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id, dxpl_id))) + H5E_clear_stack(NULL); + } /* end if */ + + /* try the 'resolved' name for the virtual file */ + if(src_file == NULL) { + char *ptr = NULL; + + /* Copy resolved file name */ + if(NULL == (actual_file_name = H5MM_strdup(H5F_ACTUAL_NAME(primary_file)))) + HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "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_FILE, H5E_CANTOPENFILE, NULL, "unable to open file, 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(H5F__build_name(actual_file_name, temp_file_name, &full_name/*out*/) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't prepend prefix to filename") + actual_file_name = (char *)H5MM_xfree(actual_file_name); + + /* Try opening with the resolved name */ + if(NULL == (src_file = H5F_efc_open(primary_file, full_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id, dxpl_id))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file, file name = '%s', temp_file_name = '%s'", file_name, temp_file_name) + full_name = (char *)H5MM_xfree(full_name); + } /* end if */ + + /* Success */ + ret_value = src_file; +done: + if((NULL == ret_value) && src_file) + if(H5F_efc_close(primary_file, src_file) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "can't close source file") + if(my_prefix) + my_prefix = (char *)H5MM_xfree(my_prefix); + if(full_name) + full_name = (char *)H5MM_xfree(full_name); + if(temp_file_name) + temp_file_name = (char *)H5MM_xfree(temp_file_name); + if(actual_file_name) + actual_file_name = (char *)H5MM_xfree(actual_file_name); + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5F_prefix_open_file() */ + + /*------------------------------------------------------------------------- * Function: H5F__is_hdf5 * @@ -528,7 +787,7 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5F__is_hdf5() */ - + /*------------------------------------------------------------------------- * Function: H5F_new * @@ -793,7 +1052,7 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_new() */ - + /*------------------------------------------------------------------------- * Function: H5F__dest * @@ -1052,7 +1311,7 @@ H5F__dest(H5F_t *f, hid_t meta_dxpl_id, hid_t raw_dxpl_id, hbool_t flush) FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_dest() */ - + /*------------------------------------------------------------------------- * Function: H5F_open * @@ -1470,7 +1729,7 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_open() */ - + /*------------------------------------------------------------------------- * Function: H5F_flush_phase1 * @@ -1507,7 +1766,7 @@ H5F__flush_phase1(H5F_t *f, hid_t meta_dxpl_id) FUNC_LEAVE_NOAPI(ret_value) } /* end H5F__flush_phase1() */ - + /*------------------------------------------------------------------------- * Function: H5F__flush_phase2 * @@ -1569,7 +1828,7 @@ H5F__flush_phase2(H5F_t *f, hid_t meta_dxpl_id, hid_t raw_dxpl_id, hbool_t closi FUNC_LEAVE_NOAPI(ret_value) } /* end H5F__flush_phase2() */ - + /*------------------------------------------------------------------------- * Function: H5F__flush * @@ -1601,7 +1860,7 @@ H5F__flush(H5F_t *f, hid_t meta_dxpl_id, hid_t raw_dxpl_id, hbool_t closing) FUNC_LEAVE_NOAPI(ret_value) } /* end H5F__flush() */ - + /*------------------------------------------------------------------------- * Function: H5F_close * @@ -1662,7 +1921,7 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_close() */ - + /*------------------------------------------------------------------------- * Function: H5F_try_close * @@ -1835,7 +2094,7 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_try_close() */ - + /*------------------------------------------------------------------------- * Function: H5F_get_id * @@ -1871,7 +2130,7 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_get_id() */ - + /*------------------------------------------------------------------------- * Function: H5F_incr_nopen_objs * @@ -1892,7 +2151,7 @@ H5F_incr_nopen_objs(H5F_t *f) FUNC_LEAVE_NOAPI(++f->nopen_objs) } /* end H5F_incr_nopen_objs() */ - + /*------------------------------------------------------------------------- * Function: H5F_decr_nopen_objs * @@ -1913,7 +2172,7 @@ H5F_decr_nopen_objs(H5F_t *f) FUNC_LEAVE_NOAPI(--f->nopen_objs) } /* end H5F_decr_nopen_objs() */ - + /*------------------------------------------------------------------------- * Function: H5F_build_actual_name * @@ -2035,7 +2294,7 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* H5F_build_actual_name() */ - + /*------------------------------------------------------------------------- * Function: H5F_addr_encode_len * @@ -2072,7 +2331,7 @@ H5F_addr_encode_len(size_t addr_len, uint8_t **pp/*in,out*/, haddr_t addr) FUNC_LEAVE_NOAPI_VOID } /* end H5F_addr_encode_len() */ - + /*------------------------------------------------------------------------- * Function: H5F_addr_encode * @@ -2096,7 +2355,7 @@ H5F_addr_encode(const H5F_t *f, uint8_t **pp/*in,out*/, haddr_t addr) FUNC_LEAVE_NOAPI_VOID } /* end H5F_addr_encode() */ - + /*------------------------------------------------------------------------- * Function: H5F_addr_decode_len * @@ -2160,7 +2419,7 @@ H5F_addr_decode_len(size_t addr_len, const uint8_t **pp/*in,out*/, haddr_t *addr FUNC_LEAVE_NOAPI_VOID } /* end H5F_addr_decode_len() */ - + /*------------------------------------------------------------------------- * Function: H5F_addr_decode * @@ -2187,7 +2446,7 @@ H5F_addr_decode(const H5F_t *f, const uint8_t **pp/*in,out*/, haddr_t *addr_p/*o FUNC_LEAVE_NOAPI_VOID } /* end H5F_addr_decode() */ - + /*------------------------------------------------------------------------- * Function: H5F_set_grp_btree_shared * @@ -2213,7 +2472,7 @@ H5F_set_grp_btree_shared(H5F_t *f, H5UC_t *rc) FUNC_LEAVE_NOAPI(SUCCEED) } /* H5F_set_grp_btree_shared() */ - + /*------------------------------------------------------------------------- * Function: H5F_set_sohm_addr * @@ -2238,7 +2497,7 @@ H5F_set_sohm_addr(H5F_t *f, haddr_t addr) FUNC_LEAVE_NOAPI(SUCCEED) } /* H5F_set_sohm_addr() */ - + /*------------------------------------------------------------------------- * Function: H5F_set_sohm_vers * @@ -2263,7 +2522,7 @@ H5F_set_sohm_vers(H5F_t *f, unsigned vers) FUNC_LEAVE_NOAPI(SUCCEED) } /* H5F_set_sohm_vers() */ - + /*------------------------------------------------------------------------- * Function: H5F_set_sohm_nindexes * @@ -2288,7 +2547,7 @@ H5F_set_sohm_nindexes(H5F_t *f, unsigned nindexes) FUNC_LEAVE_NOAPI(SUCCEED) } /* H5F_set_sohm_nindexes() */ - + /*------------------------------------------------------------------------- * Function: H5F_set_store_msg_crt_idx * @@ -2461,7 +2720,7 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* H5F_get_file_image() */ - + /*------------------------------------------------------------------------- * Function: H5F_track_metadata_read_retries * @@ -2509,7 +2768,7 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* H5F_track_metadata_read_retries() */ - + /*------------------------------------------------------------------------- * Function: H5F_set_retries * @@ -2545,7 +2804,7 @@ H5F_set_retries(H5F_t *f) FUNC_LEAVE_NOAPI(SUCCEED) } /* H5F_set_retries() */ - + /*------------------------------------------------------------------------- * Function: H5F_object_flush_cb * @@ -2575,7 +2834,7 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* H5F_object_flush_cb() */ - + /*------------------------------------------------------------------------- * Function: H5F__set_base_addr * @@ -2602,7 +2861,7 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5F__set_base_addr() */ - + /*------------------------------------------------------------------------- * Function: H5F__set_eoa * @@ -2629,7 +2888,7 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5F__set_eoa() */ - + /*------------------------------------------------------------------------- * Function: H5F__set_paged_aggr * @@ -2658,7 +2917,7 @@ done: } /* end H5F__set_paged_aggr() */ #ifdef H5_HAVE_PARALLEL - + /*------------------------------------------------------------------------- * Function: H5F_set_coll_md_read * |