diff options
author | Vailin Choi <vchoi@hdfgroup.org> | 2019-07-31 16:03:51 (GMT) |
---|---|---|
committer | Vailin Choi <vchoi@hdfgroup.org> | 2019-07-31 16:03:51 (GMT) |
commit | 452431960978a5693fb7c28096ee0f191a610b36 (patch) | |
tree | 52516e8b861e33cff4cf22443356187a7b19a58c /src | |
parent | 32e1c9f89d1685572445217d1293df2dcb0eeb13 (diff) | |
parent | 3049d2c140b06d5b2b419562c3d4d1d1c66612e3 (diff) | |
download | hdf5-452431960978a5693fb7c28096ee0f191a610b36.zip hdf5-452431960978a5693fb7c28096ee0f191a610b36.tar.gz hdf5-452431960978a5693fb7c28096ee0f191a610b36.tar.bz2 |
Merge pull request #15 in ~VCHOI/my_third_fork from hdf5_1_10 to bugfix/110_HDFFV-10808-h5pset_file_space_strategy
* commit '3049d2c140b06d5b2b419562c3d4d1d1c66612e3':
A minor bug fix.
Updated the command for external_env and vds_env to the most recent changes.
1. Updated the commands for compiling two new tests (external_env.c and vds_env.c). 2. Changed the data file names for external.c and external_env.c to avoid potential name conflict.
HDFFV-10658: setting and getting properties in API context. Porting the changes to the develop branch into the 1.10 branch: mainly the external file prefix and VDS prefix.
Diffstat (limited to 'src')
-rw-r--r-- | src/H5CX.c | 159 | ||||
-rw-r--r-- | src/H5CXprivate.h | 4 | ||||
-rw-r--r-- | src/H5Defl.c | 2 | ||||
-rw-r--r-- | src/H5Dint.c | 65 | ||||
-rw-r--r-- | src/H5Fprivate.h | 5 | ||||
-rw-r--r-- | src/H5system.c | 6 |
6 files changed, 208 insertions, 33 deletions
@@ -186,6 +186,10 @@ typedef struct H5CX_t { hid_t lapl_id; /* LAPL ID for API operation */ H5P_genplist_t *lapl; /* Link Access Property List */ + /* DAPL */ + hid_t dapl_id; /* DAPL ID for API operation */ + H5P_genplist_t *dapl; /* Dataset Access Property List */ + /* FAPL */ hid_t fapl_id; /* FAPL ID for API operation */ H5P_genplist_t *fapl; /* File Access Property List */ @@ -275,6 +279,12 @@ typedef struct H5CX_t { size_t nlinks; /* Number of soft / UD links to traverse (H5L_ACS_NLINKS_NAME) */ hbool_t nlinks_valid; /* Whether number of soft / UD links to traverse is valid */ + /* Cached DAPL properties */ + char *extfile_prefix; /* Prefix for external file */ + hbool_t extfile_prefix_valid; /* Whether the prefix for external file is valid */ + char *vds_prefix; /* Prefix for VDS */ + hbool_t vds_prefix_valid; /* Whether the prefix for VDS is valid */ + /* Cached FAPL properties */ H5F_libver_t low_bound; /* low_bound property for H5Pset_libver_bounds() */ hbool_t low_bound_valid; /* Whether low_bound property is valid */ @@ -329,6 +339,13 @@ typedef struct H5CX_lapl_cache_t { size_t nlinks; /* Number of soft / UD links to traverse (H5L_ACS_NLINKS_NAME) */ } H5CX_lapl_cache_t; +/* Typedef for cached default dataset access property list information */ +/* (Same as the cached DXPL struct, above, except for the default DXPL) */ +typedef struct H5CX_dapl_cache_t { + char *extfile_prefix; /* Prefix for external file */ + char *vds_prefix; /* Prefix for VDS */ +} H5CX_dapl_cache_t; + /* Typedef for cached default file access property list information */ /* (Same as the cached DXPL struct, above, except for the default DCPL) */ typedef struct H5CX_fapl_cache_t { @@ -367,6 +384,9 @@ static H5CX_dxpl_cache_t H5CX_def_dxpl_cache; /* Define a "default" link access property list cache structure to use for default LAPLs */ static H5CX_lapl_cache_t H5CX_def_lapl_cache; +/* Define a "default" dataset access property list cache structure to use for default DAPLs */ +static H5CX_dapl_cache_t H5CX_def_dapl_cache; + /* Define a "default" file access property list cache structure to use for default FAPLs */ static H5CX_fapl_cache_t H5CX_def_fapl_cache; @@ -390,6 +410,7 @@ H5CX__init_package(void) { H5P_genplist_t *dx_plist; /* Data transfer property list */ H5P_genplist_t *la_plist; /* Link access property list */ + H5P_genplist_t *da_plist; /* Dataset access property list */ H5P_genplist_t *fa_plist; /* File access property list */ herr_t ret_value = SUCCEED; /* Return value */ @@ -490,6 +511,23 @@ H5CX__init_package(void) if(H5P_get(la_plist, H5L_ACS_NLINKS_NAME, &H5CX_def_lapl_cache.nlinks) < 0) HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve number of soft / UD links to traverse") + /* Reset the "default DAPL cache" information */ + HDmemset(&H5CX_def_dapl_cache, 0, sizeof(H5CX_dapl_cache_t)); + + /* Get the default DAPL cache information */ + + /* Get the default dataset access property list */ + if(NULL == (da_plist = (H5P_genplist_t *)H5I_object(H5P_DATASET_ACCESS_DEFAULT))) + HGOTO_ERROR(H5E_CONTEXT, H5E_BADTYPE, FAIL, "not a dataset create property list") + + /* Get the prefix for the external file */ + if(H5P_peek(da_plist, H5D_ACS_EFILE_PREFIX_NAME, &H5CX_def_dapl_cache.extfile_prefix) < 0) + HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve prefix for external file") + + /* Get the prefix for the VDS file */ + if(H5P_peek(da_plist, H5D_ACS_VDS_PREFIX_NAME, &H5CX_def_dapl_cache.vds_prefix) < 0) + HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve prefix for VDS") + /* Reset the "default FAPL cache" information */ HDmemset(&H5CX_def_fapl_cache, 0, sizeof(H5CX_fapl_cache_t)); @@ -630,6 +668,7 @@ H5CX__push_common(H5CX_node_t *cnode) /* Set non-zero context info */ cnode->ctx.dxpl_id = H5P_DATASET_XFER_DEFAULT; cnode->ctx.lapl_id = H5P_LINK_ACCESS_DEFAULT; + cnode->ctx.dapl_id = H5P_DATASET_ACCESS_DEFAULT; cnode->ctx.fapl_id = H5P_FILE_ACCESS_DEFAULT; cnode->ctx.tag = H5AC__INVALID_TAG; cnode->ctx.ring = H5AC_RING_USER; @@ -867,6 +906,7 @@ H5CX_set_apl(hid_t *acspl_id, const H5P_libclass_t *libclass, *acspl_id = *libclass->def_plist_id; else { htri_t is_lapl; /* Whether the access property list is (or is derived from) a link access property list */ + htri_t is_dapl; /* Whether the access property list is (or is derived from) a dataset access property list */ htri_t is_fapl; /* Whether the access property list is (or is derived from) a file access property list */ #ifdef H5CX_DEBUG @@ -881,6 +921,12 @@ H5CX_set_apl(hid_t *acspl_id, const H5P_libclass_t *libclass, else if(is_lapl) (*head)->ctx.lapl_id = *acspl_id; + /* Check for dataset access property and set API context if so */ + if((is_dapl = H5P_class_isa(*libclass->pclass, *H5P_CLS_DACC->pclass)) < 0) + HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "can't check for dataset access class") + else if(is_dapl) + (*head)->ctx.dapl_id = *acspl_id; + /* Check for file access property and set API context if so */ if((is_fapl = H5P_class_isa(*libclass->pclass, *H5P_CLS_FACC->pclass)) < 0) HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "can't check for file access class") @@ -1971,6 +2017,119 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5CX_get_libver_bounds() */ +/*------------------------------------------------------------------------- + * Function: H5CX_get_ext_file_prefix + * + * Purpose: Retrieves the prefix for external file + * + * Return: Non-negative on success / Negative on failure + * + * Programmer: Raymond Lu + * March 6, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5CX_get_ext_file_prefix(char **extfile_prefix) +{ + H5CX_node_t **head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(extfile_prefix); + HDassert(head && *head); + HDassert(H5P_DEFAULT != (*head)->ctx.dapl_id); + + /* Check if the value has been retrieved already */ + if(!(*head)->ctx.extfile_prefix_valid) { + /* Check for default DAPL */ + if((*head)->ctx.dapl_id == H5P_DATASET_ACCESS_DEFAULT) + (*head)->ctx.extfile_prefix = H5CX_def_dapl_cache.extfile_prefix; + else { + /* Check if the property list is already available */ + if(NULL == (*head)->ctx.dapl) + /* Get the dataset access property list pointer */ + if(NULL == ((*head)->ctx.dapl = (H5P_genplist_t *)H5I_object((*head)->ctx.dapl_id))) + HGOTO_ERROR(H5E_CONTEXT, H5E_BADTYPE, FAIL, "can't get default dataset access property list") + + /* Get the prefix for the external file */ + /* (Note: 'peek', not 'get' - if this turns out to be a problem, we may need + * to copy it and free this in the H5CX pop routine. -QAK) + */ + if(H5P_peek((*head)->ctx.dapl, H5D_ACS_EFILE_PREFIX_NAME, &(*head)->ctx.extfile_prefix) < 0) + HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve external file prefix") + } /* end else */ + + /* Mark the value as valid */ + (*head)->ctx.extfile_prefix_valid = TRUE; + } /* end if */ + + /* Get the value */ + *extfile_prefix = (*head)->ctx.extfile_prefix; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5CX_get_ext_file_prefix() */ + + +/*------------------------------------------------------------------------- + * Function: H5CX_get_vds_prefix + * + * Purpose: Retrieves the prefix for VDS + * + * Return: Non-negative on success / Negative on failure + * + * Programmer: Raymond Lu + * March 6, 2019 + * + *------------------------------------------------------------------------- + */ +herr_t +H5CX_get_vds_prefix(char **vds_prefix) +{ + H5CX_node_t **head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(vds_prefix); + HDassert(head && *head); + HDassert(H5P_DEFAULT != (*head)->ctx.dapl_id); + + /* Check if the value has been retrieved already */ + if(!(*head)->ctx.vds_prefix_valid) { + /* Check for default DAPL */ + if((*head)->ctx.dapl_id == H5P_DATASET_ACCESS_DEFAULT) + (*head)->ctx.vds_prefix = H5CX_def_dapl_cache.vds_prefix; + else { + /* Check if the property list is already available */ + if(NULL == (*head)->ctx.dapl) + /* Get the dataset access property list pointer */ + if(NULL == ((*head)->ctx.dapl = (H5P_genplist_t *)H5I_object((*head)->ctx.dapl_id))) + HGOTO_ERROR(H5E_CONTEXT, H5E_BADTYPE, FAIL, "can't get default dataset access property list") + + /* Get the prefix for the VDS */ + /* (Note: 'peek', not 'get' - if this turns out to be a problem, we may need + * to copy it and free this in the H5CX pop routine. -QAK) + */ + if(H5P_peek((*head)->ctx.dapl, H5D_ACS_VDS_PREFIX_NAME, &(*head)->ctx.vds_prefix) < 0) + HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve VDS prefix") + } /* end else */ + + /* Mark the value as valid */ + (*head)->ctx.vds_prefix_valid = TRUE; + } /* end if */ + + /* Get the value */ + *vds_prefix = (*head)->ctx.vds_prefix; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5CX_get_vds_prefix() */ + /*------------------------------------------------------------------------- * Function: H5CX_set_tag diff --git a/src/H5CXprivate.h b/src/H5CXprivate.h index 6c01119..d67f226 100644 --- a/src/H5CXprivate.h +++ b/src/H5CXprivate.h @@ -102,6 +102,10 @@ H5_DLL herr_t H5CX_get_dt_conv_cb(H5T_conv_cb_t *cb_struct); /* "Getter" routines for LAPL properties cached in API context */ H5_DLL herr_t H5CX_get_nlinks(size_t *nlinks); +/* "Getter" routines for DAPL properties cached in API context */ +H5_DLL herr_t H5CX_get_ext_file_prefix(char **prefix_extfile); +H5_DLL herr_t H5CX_get_vds_prefix(char **prefix_vds); + /* "Getter" routines for FAPL properties cached in API context */ H5_DLL herr_t H5CX_get_libver_bounds(H5F_libver_t *low_bound, H5F_libver_t *high_bound); diff --git a/src/H5Defl.c b/src/H5Defl.c index 42b3947..ce0bb80 100644 --- a/src/H5Defl.c +++ b/src/H5Defl.c @@ -477,7 +477,6 @@ H5D__efl_readvv(const H5D_io_info_t *io_info, HDassert(io_info->u.rbuf); HDassert(io_info->dset); HDassert(io_info->dset->shared); - HDassert(io_info->dset->shared->extfile_prefix); HDassert(dset_curr_seq); HDassert(dset_len_arr); HDassert(dset_off_arr); @@ -561,7 +560,6 @@ H5D__efl_writevv(const H5D_io_info_t *io_info, HDassert(io_info->u.wbuf); HDassert(io_info->dset); HDassert(io_info->dset->shared); - HDassert(io_info->dset->shared->extfile_prefix); HDassert(dset_curr_seq); HDassert(dset_len_arr); HDassert(dset_off_arr); diff --git a/src/H5Dint.c b/src/H5Dint.c index d3cad8f..a54333f 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -54,8 +54,8 @@ static herr_t H5D__init_type(H5F_t *file, const H5D_t *dset, hid_t type_id, static herr_t H5D__cache_dataspace_info(const H5D_t *dset); static herr_t H5D__init_space(H5F_t *file, const H5D_t *dset, const H5S_t *space); static herr_t H5D__update_oh_info(H5F_t *file, H5D_t *dset, hid_t dapl_id); -static herr_t H5D__build_file_prefix(const H5D_t *dset, hid_t dapl_id, - const char *prefix_type, char **file_prefix); +static herr_t H5D__build_file_prefix(const H5D_t *dset, H5F_prefix_open_t prefix_type, + char **file_prefix); static herr_t H5D__open_oid(H5D_t *dataset, hid_t dapl_id); static herr_t H5D__init_storage(const H5D_io_info_t *io_info, hbool_t full_overwrite, hsize_t old_dim[]); @@ -112,6 +112,10 @@ static const H5I_class_t H5I_DATASET_CLS[1] = {{ /* Flag indicating "top" of interface has been initialized */ static hbool_t H5D_top_package_initialize_s = FALSE; +/* Prefixes of VDS and external file from the environment variables + * HDF5_EXTFILE_PREFIX and HDF5_VDS_PREFIX */ +const static char *H5D_prefix_ext_env = NULL; +const static char *H5D_prefix_vds_env = NULL; /*------------------------------------------------------------------------- @@ -188,6 +192,10 @@ H5D__init_package(void) /* Mark "top" of interface as initialized, too */ H5D_top_package_initialize_s = TRUE; + /* Retrieve the prefixes of VDS and external file from the environment variable */ + H5D_prefix_vds_env = HDgetenv("HDF5_VDS_PREFIX"); + H5D_prefix_ext_env = HDgetenv("HDF5_EXTFILE_PREFIX"); + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5D__init_package() */ @@ -1045,8 +1053,7 @@ done: *-------------------------------------------------------------------------- */ static herr_t -H5D__build_file_prefix(const H5D_t *dset, hid_t dapl_id, const char *prefix_type, - char **file_prefix /*out*/) +H5D__build_file_prefix(const H5D_t *dset, H5F_prefix_open_t prefix_type, char **file_prefix /*out*/) { char *prefix = NULL; /* prefix used to look for the file */ char *filepath = NULL; /* absolute path of directory the HDF5 file is in */ @@ -1067,20 +1074,22 @@ H5D__build_file_prefix(const H5D_t *dset, hid_t dapl_id, const char *prefix_type /* XXX: Future thread-safety note - getenv is not required * to be reentrant. */ - if(HDstrcmp(prefix_type, H5D_ACS_VDS_PREFIX_NAME) == 0) - prefix = HDgetenv("HDF5_VDS_PREFIX"); - else if (HDstrcmp(prefix_type, H5D_ACS_EFILE_PREFIX_NAME) == 0) - prefix = HDgetenv("HDF5_EXTFILE_PREFIX"); - else - HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "prefix name is not sensible") - - if(prefix == NULL || *prefix == '\0') { - /* Set prefix to value of prefix_type property */ - if(NULL == (plist = H5P_object_verify(dapl_id, H5P_DATASET_ACCESS))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") - if(H5P_peek(plist, prefix_type, &prefix) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get file prefix") - } /* end if */ + if(H5F_PREFIX_VDS == prefix_type) { + prefix = (char *)H5D_prefix_vds_env; + + if(prefix == NULL || *prefix == '\0') { + if(H5CX_get_vds_prefix(&prefix) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get the prefix for vds file") + } + } else if(H5F_PREFIX_EFILE == prefix_type) { + prefix = (char *)H5D_prefix_ext_env; + + if(prefix == NULL || *prefix == '\0') { + if(H5CX_get_ext_file_prefix(&prefix) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get the prefix for the external file") + } + } else + HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "prefix name is not sensible") /* Prefix has to be checked for NULL / empty string again because the * code above might have updated it. @@ -1089,8 +1098,7 @@ H5D__build_file_prefix(const H5D_t *dset, hid_t dapl_id, const char *prefix_type /* filename is interpreted as relative to the current directory, * does not need to be expanded */ - if(NULL == (*file_prefix = (char *)H5MM_strdup(""))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + *file_prefix = NULL; } /* end if */ else { if (HDstrncmp(prefix, "${ORIGIN}", HDstrlen("${ORIGIN}")) == 0) { @@ -1285,11 +1293,11 @@ H5D__create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id, HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to set up flush append property") /* Set the external file prefix */ - if(H5D__build_file_prefix(new_dset, dapl_id, H5D_ACS_EFILE_PREFIX_NAME, &new_dset->shared->extfile_prefix) < 0) + if(H5D__build_file_prefix(new_dset, H5F_PREFIX_EFILE, &new_dset->shared->extfile_prefix) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize external file prefix") /* Set the VDS file prefix */ - if(H5D__build_file_prefix(new_dset, dapl_id, H5D_ACS_VDS_PREFIX_NAME, &new_dset->shared->vds_prefix) < 0) + if(H5D__build_file_prefix(new_dset, H5F_PREFIX_VDS, &new_dset->shared->vds_prefix) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize VDS prefix") /* Add the dataset to the list of opened objects in the file */ @@ -1444,11 +1452,11 @@ H5D_open(const H5G_loc_t *loc, hid_t dapl_id) HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, NULL, "can't copy path") /* Get the external file prefix */ - if(H5D__build_file_prefix(dataset, dapl_id, H5D_ACS_EFILE_PREFIX_NAME, &extfile_prefix) < 0) + if(H5D__build_file_prefix(dataset, H5F_PREFIX_EFILE, &extfile_prefix) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize external file prefix") /* Get the VDS prefix */ - if(H5D__build_file_prefix(dataset, dapl_id, H5D_ACS_VDS_PREFIX_NAME, &vds_prefix) < 0) + if(H5D__build_file_prefix(dataset, H5F_PREFIX_VDS, &vds_prefix) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize VDS prefix") /* Check if dataset was already open */ @@ -1492,8 +1500,13 @@ H5D_open(const H5G_loc_t *loc, hid_t dapl_id) /* Check whether the external file prefix of the already open dataset * matches the new external file prefix */ - if(HDstrcmp(extfile_prefix, dataset->shared->extfile_prefix) != 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, NULL, "new external file prefix does not match external file prefix of already open dataset") + if(extfile_prefix && dataset->shared->extfile_prefix) { + if(HDstrcmp(extfile_prefix, dataset->shared->extfile_prefix) != 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, NULL, "new external file prefix does not match external file prefix of already open dataset") + } else { + if(extfile_prefix || dataset->shared->extfile_prefix) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, NULL, "new external file prefix does not match external file prefix of already open dataset") + } /* Check if the object has been opened through the top file yet */ if(H5FO_top_count(dataset->oloc.file, dataset->oloc.addr) == 0) { diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index d60c08f..5e78d9e 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -702,8 +702,9 @@ typedef enum H5F_mem_page_t { /* Type of prefix for opening prefixed files */ typedef enum H5F_prefix_open_t { - H5F_PREFIX_VDS, /* Virtual dataset prefix */ - H5F_PREFIX_ELINK /* External link prefix */ + H5F_PREFIX_VDS = 0, /* Virtual dataset prefix */ + H5F_PREFIX_ELINK = 1, /* External link prefix */ + H5F_PREFIX_EFILE = 2 /* External file prefix */ } H5F_prefix_open_t; diff --git a/src/H5system.c b/src/H5system.c index 186d8fa..41e2a48 100644 --- a/src/H5system.c +++ b/src/H5system.c @@ -1125,13 +1125,13 @@ H5_combine_path(const char* path1, const char* path2, char **full_name /*out*/) FUNC_ENTER_NOAPI_NOINIT - HDassert(path1); HDassert(path2); - path1_len = HDstrlen(path1); + if(path1) + path1_len = HDstrlen(path1); path2_len = HDstrlen(path2); - if(*path1 == '\0' || H5_CHECK_ABSOLUTE(path2)) { + if(path1 == NULL || *path1 == '\0' || H5_CHECK_ABSOLUTE(path2)) { /* If path1 is empty or path2 is absolute, simply use path2 */ if(NULL == (*full_name = (char *)H5MM_strdup(path2))) |