diff options
Diffstat (limited to 'src/H5Lexternal.c')
-rw-r--r-- | src/H5Lexternal.c | 200 |
1 files changed, 30 insertions, 170 deletions
diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c index 4e355bb..5a8eb33 100644 --- a/src/H5Lexternal.c +++ b/src/H5Lexternal.c @@ -76,81 +76,6 @@ H5L_init_extern_interface(void) } /* H5L_init_extern_interface() */ - -/*-------------------------------------------------------------------------- - * 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_NOAPI_NOINIT_NOFUNC(H5L_getenv_prefix_name) - - strret = HDstrchr(*env_prefix, COLON_SEPC); - if (strret == NULL) { - retptr = *env_prefix; - *env_prefix = strret; - } else { - retptr = *env_prefix; - *env_prefix = strret + 1; - *strret = '\0'; - } - return(retptr); - FUNC_LEAVE_NOAPI(retptr) -} - - -/*-------------------------------------------------------------------------- - * 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(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_NOAPI_NOINIT(H5L_build_name) - - 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 = H5MM_malloc(prefix_len + fname_len + 2))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate filename buffer") - - /* Copy the prefix into the buffer */ - HDstrcpy(*full_name, prefix); - if (!CHECK_DELIMITER(prefix[prefix_len-1])) - HDstrcat(*full_name, DIR_SEPS); - - /* Add the external link's filename to the prefix supplied */ - HDstrcat(*full_name, file_name); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5L_build_name() */ - - /*------------------------------------------------------------------------- * Function: H5L_extern_traverse * @@ -167,10 +92,6 @@ done: * * Programmer: James Laird * Monday, July 10, 2006 - * Modifications: - * Vailin Choi, April 2, 2008 - * Add handling to search for the target file - * See description in RM: H5Lcreate_external * *------------------------------------------------------------------------- */ @@ -193,11 +114,6 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group, hid_t ext_obj = -1; /* ID for external link's object */ hid_t ret_value; /* Return value */ - char *tempname=NULL, *ptr=NULL, *extpath=NULL; - char *env_prefix=NULL, *tmp_env_prefix=NULL; - char *out_prefix_name=NULL, *pp=NULL; - - FUNC_ENTER_NOAPI(H5L_extern_traverse, FAIL) /* Sanity checks */ @@ -219,6 +135,28 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group, if(NULL == (plist = H5P_object_verify(lapl_id, H5P_LINK_ACCESS))) HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + /* Get the current prefix */ + if(H5P_get(plist, H5L_ACS_ELINK_PREFIX_NAME, &my_prefix) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external link prefix") + + /* Check for prefix being set, if so, prepend it to the filename */ + if(my_prefix) { + size_t prefix_len = HDstrlen(my_prefix); + + /* Allocate a buffer to hold the filename plus prefix */ + if(NULL == (full_name = H5MM_malloc(prefix_len + fname_len + 1))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate filename buffer") + + /* Copy the prefix into the buffer */ + HDstrcpy(full_name, my_prefix); + + /* Add the external link's filename to the prefix supplied */ + HDstrcat(full_name, (const char *)p); + + /* Point to name w/prefix */ + file_name = full_name; + } /* end if */ + /* Get the location for the group holding the external link */ if(H5G_loc(cur_group, &loc) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get object location") @@ -245,92 +183,10 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group, HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file close degree") } /* end if */ - /* - * Start searching for the target file - */ - if ((tempname=H5MM_strdup(file_name)) == NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - - /* target file_name is an absolute pathname: see RM for detailed description */ - if (CHECK_ABSOLUTE(file_name) || CHECK_ABS_PATH(file_name)) { - if(NULL == (ext_file = H5F_open(file_name, ((intent & H5F_ACC_RDWR) ? H5F_ACC_RDWR : H5F_ACC_RDONLY), - H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) { - H5E_clear_stack(NULL); - /* get last component of file_name */ - GET_LAST_DELIMITER(file_name, ptr) - HDassert(ptr); - HDstrcpy(tempname, ++ptr); - } - } else if (CHECK_ABS_DRIVE(file_name)) { - if(NULL == (ext_file = H5F_open(file_name, ((intent & H5F_ACC_RDWR) ? H5F_ACC_RDWR : H5F_ACC_RDONLY), - H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) { - H5E_clear_stack(NULL); - /* strip "<drive-letter>:" */ - HDstrcpy(tempname, &file_name[2]); - } - } - - /* try searching from paths set in the environment variable */ - if ((ext_file == NULL) && (env_prefix=HDgetenv("HDF5_EXT_PREFIX"))) { - - tmp_env_prefix = H5MM_strdup(env_prefix); - pp = tmp_env_prefix; - - while ((tmp_env_prefix) && (*tmp_env_prefix)) { - 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, tempname, &full_name/*out*/) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't prepend prefix to filename") - - ext_file = H5F_open(full_name, ((intent & H5F_ACC_RDWR) ? H5F_ACC_RDWR : H5F_ACC_RDONLY), - H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id); - if (full_name) - H5MM_xfree(full_name); - if (ext_file != NULL) - break; - H5E_clear_stack(NULL); - } - } /* end while */ - if (pp) - H5MM_xfree(pp); - } - - /* try searching from property list */ - if (ext_file == NULL) { - if(H5P_get(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, tempname, &full_name/*out*/) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't prepend prefix to filename") - if ((ext_file=H5F_open(full_name, ((intent & H5F_ACC_RDWR) ? H5F_ACC_RDWR : H5F_ACC_RDONLY), - H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id)) == NULL) - H5E_clear_stack(NULL); - if (full_name) - H5MM_xfree(full_name); - } - } - - /* try searching from main file's "extpath":see description in H5F_open() & H5_build_extpath() */ - if ((ext_file == NULL) && (extpath=H5F_EXTPATH(loc.oloc->file))) { - if (H5L_build_name(extpath, tempname, &full_name/*out*/) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't prepend prefix to filename") - if ((ext_file = H5F_open(full_name, ((intent & H5F_ACC_RDWR) ? H5F_ACC_RDWR : H5F_ACC_RDONLY), - H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id)) == NULL) - H5E_clear_stack(NULL); - if (full_name) - H5MM_xfree(full_name); - } - - /* try the relative file_name stored in tempname */ - if (ext_file == NULL) { - if ((ext_file=H5F_open(tempname, ((intent & H5F_ACC_RDWR) ? H5F_ACC_RDWR : H5F_ACC_RDONLY), - H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id)) == NULL) - HGOTO_ERROR(H5E_LINK, H5E_CANTOPENFILE, FAIL, "unable to open external file") - } - - if (tempname) - H5MM_xfree(tempname); + /* Open the external file */ + /* (extra work with file intent to mask off inappropriate flags) */ + if(NULL == (ext_file = H5F_open(file_name, ((intent & H5F_ACC_RDWR) ? H5F_ACC_RDWR : H5F_ACC_RDONLY), H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) + HGOTO_ERROR(H5E_LINK, H5E_CANTOPENFILE, FAIL, "unable to open external file") /* Increment the number of open objects, to hold the file open */ H5F_incr_nopen_objs(ext_file); @@ -363,6 +219,10 @@ done: if(ext_file && H5F_try_close(ext_file) < 0) HDONE_ERROR(H5E_LINK, H5E_CANTCLOSEFILE, FAIL, "problem closing external file") + /* Free full_name if it's been allocated */ + if(full_name) + H5MM_xfree(full_name); + /* Close object if it's open and something failed */ if(ret_value < 0 && ext_obj >= 0 && H5I_dec_ref(ext_obj) < 0) HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom for external object") |