diff options
-rw-r--r-- | src/H5F.c | 32 | ||||
-rw-r--r-- | src/H5FDcore.c | 105 | ||||
-rw-r--r-- | src/H5FDsec2.c | 9 | ||||
-rw-r--r-- | src/H5Fprivate.h | 3 | ||||
-rw-r--r-- | src/H5Pfapl.c | 19 | ||||
-rw-r--r-- | src/H5Pint.c | 2 | ||||
-rw-r--r-- | src/H5Pprivate.h | 2 | ||||
-rw-r--r-- | test/links.c | 5 |
8 files changed, 119 insertions, 58 deletions
@@ -69,6 +69,8 @@ static size_t H5F_get_objects(const H5F_t *f, unsigned types, size_t max_objs, h static int H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key); static H5F_t *H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf); +static herr_t H5F_build_actual_name(const H5F_t *f, const H5P_genplist_t *fapl, + const char *name, char ** /*out*/ actual_name); static herr_t H5F_dest(H5F_t *f, hid_t dxpl_id); static herr_t H5F_close(H5F_t *f); @@ -1142,7 +1144,8 @@ H5F_dest(H5F_t *f, hid_t dxpl_id) *------------------------------------------------------------------------- */ H5F_t * -H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id) +H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, + hid_t dxpl_id) { H5F_t *file = NULL; /*the success return value */ H5F_file_t *shared = NULL; /*shared part of `file' */ @@ -1312,7 +1315,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to build extpath") /* Formulate the actual file name, after following symlinks, etc. */ - if(H5F_build_actual_name(file, name, &file->actual_name) < 0) + if(H5F_build_actual_name(file, a_plist, name, &file->actual_name) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to build actual name") /* Success */ @@ -2147,15 +2150,18 @@ H5F_decr_nopen_objs(H5F_t *f) * *------------------------------------------------------------------------- */ -herr_t -H5F_build_actual_name(const H5F_t *f, const char *name, char **actual_name/*out*/) +static herr_t +H5F_build_actual_name(const H5F_t *f, const H5P_genplist_t *fapl, const char *name, + char **actual_name/*out*/) { + hid_t new_fapl_id = -1; /* ID for duplicated FAPL */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5F_build_actual_name) /* Sanity check */ HDassert(f); + HDassert(fapl); HDassert(name); HDassert(actual_name); @@ -2176,10 +2182,12 @@ H5F_build_actual_name(const H5F_t *f, const char *name, char **actual_name/*out* /* Check for symbolic link */ if(S_IFLNK == (lst.st_mode & S_IFMT)) { + H5P_genplist_t *new_fapl; /* Duplicated FAPL */ int *fd; /* POSIX I/O file descriptor */ h5_stat_t st; /* Stat info from stat() call */ h5_stat_t fst; /* Stat info from fstat() call */ char realname[PATH_MAX]; /* Fully resolved path name of file */ + hbool_t want_posix_fd; /* Flag for retrieving file descriptor from VFD */ /* Perform a sanity check that the file or link wasn't switched * between when we opened it and when we called lstat(). This is @@ -2187,8 +2195,19 @@ H5F_build_actual_name(const H5F_t *f, const char *name, char **actual_name/*out* * here: https://www.securecoding.cert.org/confluence/display/seccode/POS35-C.+Avoid+race+conditions+while+checking+for+the+existence+of+a+symbolic+link */ + /* Copy the FAPL object to modify */ + if((new_fapl_id = H5P_copy_plist(fapl, FALSE)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy file access property list") + if(NULL == (new_fapl = (H5P_genplist_t *)H5I_object(new_fapl_id))) + HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, FAIL, "can't get property list") + + /* Set the character encoding on the new property list */ + want_posix_fd = TRUE; + if(H5P_set(new_fapl, H5F_ACS_WANT_POSIX_FD_NAME, &want_posix_fd) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set character encoding") + /* Retrieve the file handle */ - if(H5F_get_vfd_handle(f, H5P_DEFAULT, (void **)&fd) < 0) + if(H5F_get_vfd_handle(f, new_fapl_id, (void **)&fd) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve POSIX file descriptor") /* Stat the filename we're resolving */ @@ -2222,6 +2241,9 @@ H5F_build_actual_name(const H5F_t *f, const char *name, char **actual_name/*out* } /* end else */ done: + if(new_fapl_id > 0 && H5Pclose(new_fapl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "can't close duplicated FAPL") + FUNC_LEAVE_NOAPI(ret_value) } /* H5F_build_actual_name() */ diff --git a/src/H5FDcore.c b/src/H5FDcore.c index a08abdd..2d754f5 100644 --- a/src/H5FDcore.c +++ b/src/H5FDcore.c @@ -398,29 +398,29 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id, FUNC_ENTER_NOAPI(H5FD_core_open, NULL) /* Check arguments */ - if (!name || !*name) + if(!name || !*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid file name") - if (0==maxaddr || HADDR_UNDEF==maxaddr) + if(0 == maxaddr || HADDR_UNDEF == maxaddr) HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr") if(ADDR_OVERFLOW(maxaddr)) HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, NULL, "maxaddr overflow") - assert(H5P_DEFAULT != fapl_id); - if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list") - fa = (H5FD_core_fapl_t *)H5P_get_driver_info(plist); + HDassert(H5P_DEFAULT != fapl_id); + if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list") + fa = (H5FD_core_fapl_t *)H5P_get_driver_info(plist); /* Build the open flags */ o_flags = (H5F_ACC_RDWR & flags) ? O_RDWR : O_RDONLY; - if (H5F_ACC_TRUNC & flags) o_flags |= O_TRUNC; - if (H5F_ACC_CREAT & flags) o_flags |= O_CREAT; - if (H5F_ACC_EXCL & flags) o_flags |= O_EXCL; + if(H5F_ACC_TRUNC & flags) o_flags |= O_TRUNC; + if(H5F_ACC_CREAT & flags) o_flags |= O_CREAT; + if(H5F_ACC_EXCL & flags) o_flags |= O_EXCL; /* Open backing store. The only case that backing store is off is when * the backing_store flag is off and H5F_ACC_CREAT is on. */ if(fa->backing_store || !(H5F_ACC_CREAT & flags)) { - if (fa && (fd=HDopen(name, o_flags, 0666))<0) + if(fa && (fd = HDopen(name, o_flags, 0666)) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file") - } + } /* end if */ /* Create the new file struct */ if(NULL == (file = (H5FD_core_t *)H5MM_calloc(sizeof(H5FD_core_t)))) @@ -441,35 +441,34 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id, /* If an existing file is opened, load the whole file into memory. */ if(!(H5F_ACC_CREAT & flags)) { - unsigned char *x=NULL; size_t size; - if (HDfstat(file->fd, &sb)<0) + /* stat() file to retrieve its size */ + if(HDfstat(file->fd, &sb) < 0) HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, "unable to fstat file") - size = (size_t)sb.st_size; + /* Check if we should allocate the memory buffer and read in existing data */ if(size) { - if (NULL==file->mem) - x = (unsigned char*)H5MM_malloc(size); - - if (!x) + /* Allocate memory for the file's data */ + if(NULL == (file->mem = (unsigned char*)H5MM_malloc(size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate memory block") - file->mem = x; + /* Set up data structures */ file->eof = size; - if(HDread(file->fd, file->mem, size)<0) + /* Read in existing data */ + if(HDread(file->fd, file->mem, size) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read file") - } - } + } /* end if */ + } /* end if */ /* Set return value */ - ret_value=(H5FD_t *)file; + ret_value = (H5FD_t *)file; done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5FD_core_open() */ /*------------------------------------------------------------------------- @@ -576,13 +575,12 @@ done: * *------------------------------------------------------------------------- */ -/* ARGSUSED */ static herr_t -H5FD_core_query(const H5FD_t UNUSED * _f, unsigned long *flags /* out */) +H5FD_core_query(const H5FD_t * _file, unsigned long *flags /* out */) { - herr_t ret_value = SUCCEED; /* Return value */ + const H5FD_core_t *file = (const H5FD_core_t*)_file; - FUNC_ENTER_NOAPI(H5FD_core_query, FAIL) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_core_query) /* Set the VFL feature flags that this driver supports */ if(flags) { @@ -591,10 +589,13 @@ H5FD_core_query(const H5FD_t UNUSED * _f, unsigned long *flags /* out */) *flags |= H5FD_FEAT_ACCUMULATE_METADATA; /* OK to accumulate metadata for faster writes */ *flags |= H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */ *flags |= H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */ + + /* If the backing store is open, a POSIX file handle is available */ + if(file->fd >= 0 && file->backing_store) + *flags |= H5FD_FEAT_POSIX_COMPAT_HANDLE; /* VFD handle is POSIX I/O call compatible */ } /* end if */ -done: - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5FD_core_query() */ @@ -622,9 +623,8 @@ done: static haddr_t H5FD_core_get_eoa(const H5FD_t *_file, H5FD_mem_t UNUSED type) { - haddr_t ret_value; /* Return value */ - const H5FD_core_t *file = (const H5FD_core_t*)_file; + haddr_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5FD_core_get_eoa, HADDR_UNDEF) @@ -726,23 +726,52 @@ done: * *------------------------------------------------------------------------- */ -/* ARGSUSED */ static herr_t -H5FD_core_get_handle(H5FD_t *_file, hid_t UNUSED fapl, void** file_handle) +H5FD_core_get_handle(H5FD_t *_file, hid_t fapl, void** file_handle) { - H5FD_core_t *file = (H5FD_core_t *)_file; - herr_t ret_value = SUCCEED; + H5FD_core_t *file = (H5FD_core_t *)_file; /* core VFD info */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5FD_core_get_handle, FAIL) + /* Check args */ if(!file_handle) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file handle not valid") - *file_handle = &(file->mem); + /* Check for non-default FAPL */ + if(H5P_FILE_ACCESS_DEFAULT != fapl && H5P_DEFAULT != fapl) { + H5P_genplist_t *plist; /* Property list pointer */ + + /* Get the FAPL */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl))) + HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, FAIL, "not a file access property list") + + /* Check if private property for retrieving the backing store POSIX + * file descriptor is set. (This should not be set except within the + * library) QAK - 2009/12/04 + */ + if(H5P_exist_plist(plist, H5F_ACS_WANT_POSIX_FD_NAME) > 0) { + hbool_t want_posix_fd; /* Setting for retrieving file descriptor from core VFD */ + + /* Get property */ + if(H5P_get(plist, H5F_ACS_WANT_POSIX_FD_NAME, &want_posix_fd) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get property of retrieving file descriptor") + + /* If property is set, pass back the file descriptor instead of the memory address */ + if(want_posix_fd) + *file_handle = &(file->fd); + else + *file_handle = &(file->mem); + } /* end if */ + else + *file_handle = &(file->mem); + } /* end if */ + else + *file_handle = &(file->mem); done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5FD_core_get_handle() */ /*------------------------------------------------------------------------- diff --git a/src/H5FDsec2.c b/src/H5FDsec2.c index a030934..c715aae 100644 --- a/src/H5FDsec2.c +++ b/src/H5FDsec2.c @@ -328,19 +328,18 @@ done: * *------------------------------------------------------------------------- */ -/* ARGSUSED */ static H5FD_t * H5FD_sec2_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) { - int o_flags; - int fd=(-1); - H5FD_sec2_t *file=NULL; + H5FD_sec2_t *file = NULL; /* sec2 VFD info */ + int fd = (-1); /* File descriptor */ + int o_flags; /* Flags for open() call */ #ifdef _WIN32 HFILE filehandle; struct _BY_HANDLE_FILE_INFORMATION fileinfo; #endif h5_stat_t sb; - H5FD_t *ret_value; + H5FD_t *ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5FD_sec2_open, NULL) diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index c55c616..f7df7f7 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -380,6 +380,7 @@ typedef struct H5F_blk_aggr_t H5F_blk_aggr_t; #define H5F_ACS_FAMILY_TO_SEC2_NAME "family_to_sec2" /* Whether to convert family to sec2 driver. (private property only used by h5repart) */ #define H5F_ACS_MULTI_TYPE_NAME "multi_type" /* Data type in multi file driver */ #define H5F_ACS_LATEST_FORMAT_NAME "latest_format" /* 'Use latest format version' flag */ +#define H5F_ACS_WANT_POSIX_FD_NAME "want_posix_fd" /* Internal: query the file descriptor from the core VFD, instead of the memory address */ /* ======================== File Mount properties ====================*/ #define H5F_MNT_SYM_LOCAL_NAME "local" /* Whether absolute symlinks local to file. */ @@ -475,8 +476,6 @@ H5_DLL H5F_t *H5F_open(const char *name, unsigned flags, hid_t fcpl_id, H5_DLL herr_t H5F_try_close(H5F_t *f); H5_DLL unsigned H5F_incr_nopen_objs(H5F_t *f); H5_DLL unsigned H5F_decr_nopen_objs(H5F_t *f); -H5_DLL herr_t H5F_build_actual_name(const H5F_t *f, const char *, - char ** /*out*/ ); /* Functions than retrieve values from the file struct */ H5_DLL unsigned H5F_get_intent(const H5F_t *f); diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c index e082e9c..486bda3 100644 --- a/src/H5Pfapl.c +++ b/src/H5Pfapl.c @@ -101,18 +101,23 @@ #define H5F_ACS_FAMILY_OFFSET_DEF 0 /* Definition for new member size of family driver. It's private * property only used by h5repart */ -#define H5F_ACS_FAMILY_NEWSIZE_SIZE sizeof(hsize_t) -#define H5F_ACS_FAMILY_NEWSIZE_DEF 0 +#define H5F_ACS_FAMILY_NEWSIZE_SIZE sizeof(hsize_t) +#define H5F_ACS_FAMILY_NEWSIZE_DEF 0 /* Definition for whether to convert family to sec2 driver. It's private * property only used by h5repart */ -#define H5F_ACS_FAMILY_TO_SEC2_SIZE sizeof(hbool_t) -#define H5F_ACS_FAMILY_TO_SEC2_DEF FALSE +#define H5F_ACS_FAMILY_TO_SEC2_SIZE sizeof(hbool_t) +#define H5F_ACS_FAMILY_TO_SEC2_DEF FALSE /* Definition for data type in multi file driver */ #define H5F_ACS_MULTI_TYPE_SIZE sizeof(H5FD_mem_t) #define H5F_ACS_MULTI_TYPE_DEF H5FD_MEM_DEFAULT /* Definition for 'use latest format version' flag */ #define H5F_ACS_LATEST_FORMAT_SIZE sizeof(hbool_t) #define H5F_ACS_LATEST_FORMAT_DEF FALSE +/* Definition for whether to query the file descriptor from the core VFD + * instead of the memory address. (Private to library) + */ +#define H5F_ACS_WANT_POSIX_FD_SIZE sizeof(hbool_t) +#define H5F_ACS_WANT_POSIX_FD_DEF FALSE /******************/ @@ -204,6 +209,7 @@ H5P_facc_reg_prop(H5P_genclass_t *pclass) hbool_t family_to_sec2 = H5F_ACS_FAMILY_TO_SEC2_DEF; /* Default ?? for family VFD */ H5FD_mem_t mem_type = H5F_ACS_MULTI_TYPE_DEF; /* Default file space type for multi VFD */ hbool_t latest_format = H5F_ACS_LATEST_FORMAT_DEF; /* Default setting for "use the latest version of the format" flag */ + hbool_t want_posix_fd = H5F_ACS_WANT_POSIX_FD_DEF; /* Default setting for retrieving 'handle' from core VFD */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5P_facc_reg_prop) @@ -280,6 +286,11 @@ H5P_facc_reg_prop(H5P_genclass_t *pclass) if(H5P_register(pclass, H5F_ACS_LATEST_FORMAT_NAME, H5F_ACS_LATEST_FORMAT_SIZE, &latest_format, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + /* Register the private property of whether to retrieve the file descriptor from the core VFD */ + /* (used internally to the library only) */ + if(H5P_register(pclass, H5F_ACS_WANT_POSIX_FD_NAME, H5F_ACS_WANT_POSIX_FD_SIZE, &want_posix_fd, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5P_facc_reg_prop() */ diff --git a/src/H5Pint.c b/src/H5Pint.c index 4da7f09..7111cba 100644 --- a/src/H5Pint.c +++ b/src/H5Pint.c @@ -619,7 +619,7 @@ done: REVISION LOG --------------------------------------------------------------------------*/ hid_t -H5P_copy_plist(H5P_genplist_t *old_plist, hbool_t app_ref) +H5P_copy_plist(const H5P_genplist_t *old_plist, hbool_t app_ref) { H5P_genclass_t *tclass; /* Temporary class pointer */ H5P_genplist_t *new_plist=NULL; /* New property list generated from copy */ diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h index 0b37938..f544dbc 100644 --- a/src/H5Pprivate.h +++ b/src/H5Pprivate.h @@ -58,7 +58,7 @@ H5_DLL herr_t H5P_init(void); /* Internal versions of API routines */ H5_DLL herr_t H5P_close(void *_plist); H5_DLL hid_t H5P_create_id(H5P_genclass_t *pclass, hbool_t app_ref); -H5_DLL hid_t H5P_copy_plist(H5P_genplist_t *old_plist, hbool_t app_ref); +H5_DLL hid_t H5P_copy_plist(const H5P_genplist_t *old_plist, hbool_t app_ref); H5_DLL herr_t H5P_get(const H5P_genplist_t *plist, const char *name, void *value); H5_DLL herr_t H5P_set(H5P_genplist_t *plist, const char *name, const void *value); H5_DLL herr_t H5P_insert(H5P_genplist_t *plist, const char *name, size_t size, diff --git a/test/links.c b/test/links.c index 84d2542..deae5ef 100644 --- a/test/links.c +++ b/test/links.c @@ -6434,10 +6434,11 @@ external_symlink(const char *env_h5_drvr, hid_t fapl, hbool_t new_format) TESTING("external links w/symlink files") #ifdef H5_HAVE_SYMLINK - /* Skip test when using VFDs that have their own 'alloc' callback, which - * don't push mis-aligned space fragments on the file free space list + /* Skip test when using VFDs that can't provide a POSIX compatible file + * descriptor. */ have_posix_compat_vfd = (hbool_t)(!HDstrcmp(env_h5_drvr, "sec2") + || !HDstrcmp(env_h5_drvr, "core") || !HDstrcmp(env_h5_drvr, "nomatch")); if(have_posix_compat_vfd) { /* set up name for main file: "extlinks21A" */ |