summaryrefslogtreecommitdiffstats
path: root/src/H5F.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5F.c')
-rw-r--r--src/H5F.c198
1 files changed, 117 insertions, 81 deletions
diff --git a/src/H5F.c b/src/H5F.c
index 064988e..68a5789 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -67,7 +67,6 @@ typedef struct H5F_olist_t {
/* PRIVATE PROTOTYPES */
static size_t H5F_get_objects(const H5F_t *f, unsigned types, size_t max_objs, hid_t *obj_id_list, hbool_t app_ref);
static int H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key);
-static herr_t H5F_get_vfd_handle(const H5F_t *file, hid_t fapl, void** file_handle);
static H5F_t *H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id,
H5FD_t *lf);
static herr_t H5F_dest(H5F_t *f, hid_t dxpl_id);
@@ -705,21 +704,18 @@ done:
* driver.
*
* Return: Success: non-negative value.
- *
- * Failture: negative.
+ * Failure: negative.
*
* Programmer: Raymond Lu
* Sep. 16, 2002
*
- * Modification:
- *
*-------------------------------------------------------------------------
*/
herr_t
H5Fget_vfd_handle(hid_t file_id, hid_t fapl, void **file_handle)
{
H5F_t *file; /* File to query */
- herr_t ret_value; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(H5Fget_vfd_handle, FAIL)
H5TRACE3("e", "ii**x", file_id, fapl, file_handle);
@@ -732,7 +728,9 @@ H5Fget_vfd_handle(hid_t file_id, hid_t fapl, void **file_handle)
if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file id")
- ret_value = H5F_get_vfd_handle(file, fapl, file_handle);
+ /* Retrieve the VFD handle for the file */
+ if(H5F_get_vfd_handle(file, fapl, file_handle) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve VFD handle")
done:
FUNC_LEAVE_API(ret_value)
@@ -740,39 +738,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5F_get_vfd_handle
- *
- * Purpose: Returns a pointer to the file handle of the low-level file
- * driver. This is the private function for H5Fget_vfd_handle.
- *
- * Return: Success: Non-negative.
- *
- * Failture: negative.
- *
- * Programmer: Raymond Lu
- * Sep. 16, 2002
- *
- * Modification:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5F_get_vfd_handle(const H5F_t *file, hid_t fapl, void**file_handle)
-{
- herr_t ret_value;
-
- FUNC_ENTER_NOAPI_NOINIT(H5F_get_vfd_handle)
-
- assert(file_handle);
- if((ret_value=H5FD_get_vfd_handle(file->shared->lf, fapl, file_handle)) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get file handle for file driver")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
-
-
-/*-------------------------------------------------------------------------
* Function: H5Fis_hdf5
*
* Purpose: Check the file signature to detect an HDF5 file.
@@ -1118,7 +1083,8 @@ H5F_dest(H5F_t *f, hid_t dxpl_id)
}
/* Free the non-shared part of the file */
- f->name = (char *)H5MM_xfree(f->name);
+ f->open_name = (char *)H5MM_xfree(f->open_name);
+ f->actual_name = (char *)H5MM_xfree(f->actual_name);
f->extpath = (char *)H5MM_xfree(f->extpath);
if(H5FO_top_dest(f) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "problems closing file")
@@ -1168,7 +1134,6 @@ H5F_dest(H5F_t *f, hid_t dxpl_id)
* cause the default file access parameters to be used.
*
* Return: Success: A new file pointer.
- *
* Failure: NULL
*
* Programmer: Robb Matzke
@@ -1198,7 +1163,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d
* Otherwise it is the application's responsibility to never open the
* same file more than once at a time.
*/
- if((drvr = H5FD_get_class(fapl_id)) == NULL)
+ if(NULL == (drvr = H5FD_get_class(fapl_id)))
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to retrieve VFL class")
/*
@@ -1291,7 +1256,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d
* file can be accessed through the C library.
*/
file->intent = flags;
- file->name = H5MM_xstrdup(name);
+ file->open_name = H5MM_xstrdup(name);
/*
* Read or write the file superblock, depending on whether the file is
@@ -1349,10 +1314,14 @@ 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, "file close degree doesn't match")
} /* end if */
- /* formulate the absolute path for later search of target file for external link */
- if (H5_build_extpath(name, &file->extpath) < 0)
+ /* Formulate the absolute path for later search of target file for external links */
+ if(H5_build_extpath(name, &file->extpath) < 0)
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)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to build actual name")
+
/* Success */
ret_value = file;
@@ -2020,8 +1989,9 @@ H5Freopen(hid_t file_id)
/* Keep old file's read/write intent in new file */
new_file->intent = old_file->intent;
- /* Duplicate old file's name */
- new_file->name = H5MM_xstrdup(old_file->name);
+ /* Duplicate old file's names */
+ new_file->open_name = H5MM_xstrdup(old_file->open_name);
+ new_file->actual_name = H5MM_xstrdup(old_file->actual_name);
if((ret_value = H5I_register(H5I_FILE, new_file, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file handle")
@@ -2132,37 +2102,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5F_get_eoa
- *
- * Purpose: Quick and dirty routine to retrieve the file's 'eoa' value
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
- * June 1, 2004
- *
- *-------------------------------------------------------------------------
- */
-haddr_t
-H5F_get_eoa(const H5F_t *f, H5FD_mem_t type)
-{
- haddr_t ret_value;
-
- FUNC_ENTER_NOAPI(H5F_get_eoa, HADDR_UNDEF)
-
- HDassert(f);
- HDassert(f->shared);
-
- /* Dispatch to driver */
- if(HADDR_UNDEF == (ret_value = H5FD_get_eoa(f->shared->lf, type)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "driver get_eoa request failed")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5F_get_eoa() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5F_incr_nopen_objs
*
* Purpose: Increment the number of open objects for a file.
@@ -2217,6 +2156,100 @@ H5F_decr_nopen_objs(H5F_t *f)
/*-------------------------------------------------------------------------
+ * Function: H5F_build_actual_name
+ *
+ * Purpose: Retrieve the name of a file, after following symlinks, etc.
+ *
+ * Note: Currently only working for "POSIX I/O compatible" VFDs
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * November 25, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_build_actual_name(const H5F_t *f, const char *name, char **actual_name/*out*/)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5F_build_actual_name)
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(name);
+ HDassert(actual_name);
+
+ /* Clear actual name pointer to begin with */
+ *actual_name = NULL;
+
+/* Assume that if the OS can't create symlinks, that we don't need to worry
+ * about resolving them either. -QAK
+ */
+#ifdef H5_HAVE_SYMLINK
+ /* Check for POSIX I/O compatible file handle */
+ if(H5F_HAS_FEATURE(f, H5FD_FEAT_POSIX_COMPAT_HANDLE)) {
+ h5_stat_t lst; /* Stat info from lstat() call */
+
+ /* Call lstat() on the file's name */
+ if(HDlstat(name, &lst) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve stat info for file")
+
+ /* Check for symbolic link */
+ if(S_IFLNK == (lst.st_mode & S_IFMT)) {
+ 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 */
+
+ /* Perform a sanity check that the file or link wasn't switched
+ * between when we opened it and when we called lstat(). This is
+ * according to the security best practices for lstat() documented
+ * here: https://www.securecoding.cert.org/confluence/display/seccode/POS35-C.+Avoid+race+conditions+while+checking+for+the+existence+of+a+symbolic+link
+ */
+
+ /* Retrieve the file handle */
+ if(H5F_get_vfd_handle(f, H5P_DEFAULT, (void **)&fd) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve POSIX file descriptor")
+
+ /* Stat the filename we're resolving */
+ if(HDstat(name, &st) < 0)
+ HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to stat file")
+
+ /* Stat the file we opened */
+ if(HDfstat(*fd, &fst) < 0)
+ HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to fstat file")
+
+ /* Verify that the files are really the same */
+ if(st.st_mode != fst.st_mode || st.st_ino != fst.st_ino || st.st_dev != fst.st_dev)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "files' st_ino or st_dev fields changed!")
+
+ /* Get the resolved path for the file name */
+ if(NULL == HDrealpath(name, realname))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve real path for file")
+
+ /* Duplicate the resolved path for the file name */
+ if(NULL == (*actual_name = (char *)H5MM_strdup(realname)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "can't duplicate real path")
+ } /* end if */
+ } /* end if */
+#endif /* H5_HAVE_SYMLINK */
+
+ /* Check if we've resolved the file's name */
+ if(NULL == *actual_name) {
+ /* Just duplicate the name used to open the file */
+ if(NULL == (*actual_name = (char *)H5MM_strdup(name)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "can't duplicate open name")
+ } /* end else */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5F_build_actual_name() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5F_addr_encode_len
*
* Purpose: Encodes an address into the buffer pointed to by *PP and
@@ -2752,6 +2785,9 @@ done:
* If an error occurs then the buffer pointed to by `name' (NULL or non-NULL)
* is unchanged and the function returns a negative value.
*
+ * Note: This routine returns the name that was used to open the file,
+ * not the actual name after resolving symlinks, etc.
+ *
* Return: Success: The length of the file name
* Failure: Negative
*
@@ -2787,10 +2823,10 @@ H5Fget_name(hid_t obj_id, char *name/*out*/, size_t size)
f = loc.oloc->file;
} /* end else */
- len = HDstrlen(f->name);
+ len = HDstrlen(H5F_OPEN_NAME(f));
if(name) {
- HDstrncpy(name, f->name, MIN(len+1,size));
+ HDstrncpy(name, H5F_OPEN_NAME(f), MIN(len + 1,size));
if(len >= size)
name[size-1]='\0';
} /* end if */