summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5F.c45
-rw-r--r--src/H5Fpublic.h1
-rw-r--r--src/H5Lexternal.c11
-rw-r--r--test/links.c19
-rw-r--r--test/tfile.c31
5 files changed, 103 insertions, 4 deletions
diff --git a/src/H5F.c b/src/H5F.c
index 80fccd3..cb24a4a 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -2729,6 +2729,51 @@ done:
HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file")
FUNC_LEAVE_API(ret_value)
}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Fget_intent
+ *
+ * Purpose: Public API to retrieve the file's 'intent' flags passed
+ * during H5Fopen()
+ *
+ * Return: Non-negative on success/negative on failure
+ *
+ * Programmer: James Laird
+ * August 23, 2006
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Fget_intent(hid_t file_id, unsigned *intent_flags)
+{
+ H5F_t * file = NULL;
+ herr_t ret_value;
+ FUNC_ENTER_API(H5Fget_intent, FAIL)
+
+ if (NULL==(file=H5I_object_verify(file_id, H5I_FILE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
+
+ /* If no intent flags were passed in, exit quietly */
+ if(!intent_flags)
+ HGOTO_DONE(SUCCEED)
+
+ *intent_flags = H5F_get_intent(file);
+
+ /* HDF5 uses some flags internally that users don't know about.
+ * Simplify things for them so that they get one of H5F_ACC_RDWR
+ * or H5F_ACC_RDONLY.
+ */
+ if(*intent_flags & H5F_ACC_RDWR)
+ *intent_flags = H5F_ACC_RDWR;
+ else
+ *intent_flags = H5F_ACC_RDONLY;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+}
/*-------------------------------------------------------------------------
diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h
index 7243c98..d3ae119 100644
--- a/src/H5Fpublic.h
+++ b/src/H5Fpublic.h
@@ -114,6 +114,7 @@ H5_DLL herr_t H5Fflush(hid_t object_id, H5F_scope_t scope);
H5_DLL herr_t H5Fclose (hid_t file_id);
H5_DLL hid_t H5Fget_create_plist (hid_t file_id);
H5_DLL hid_t H5Fget_access_plist (hid_t file_id);
+H5_DLL herr_t H5Fget_intent(hid_t file_id, unsigned * intent);
H5_DLL int H5Fget_obj_count(hid_t file_id, unsigned types);
H5_DLL int H5Fget_obj_ids(hid_t file_id, unsigned types, int max_objs, hid_t *obj_id_list);
H5_DLL herr_t H5Fget_vfd_handle(hid_t file_id, hid_t fapl, void** file_handle);
diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c
index 612c4c6..3452c20 100644
--- a/src/H5Lexternal.c
+++ b/src/H5Lexternal.c
@@ -53,6 +53,7 @@ static hid_t H5L_extern_traverse(const char * link_name, hid_t cur_group, void *
char *prefix;
size_t fname_len;
hbool_t fname_alloc = FALSE;
+ unsigned intent;
hid_t ret_value = -1;
file_name = (char *) udata;
@@ -79,7 +80,15 @@ static hid_t H5L_extern_traverse(const char * link_name, hid_t cur_group, void *
strcat(file_name, udata);
}
- if((fid = H5Fopen(file_name, H5F_ACC_RDWR, H5P_DEFAULT)) < 0)
+ /* Figure out if we should open with read-write or read-only */
+ if((fid = H5Iget_file_id(cur_group)) < 0)
+ goto error;
+ if(H5Fget_intent(fid, &intent) < 0)
+ goto error;
+ if(H5Fclose(fid) < 0)
+ goto error;
+
+ if((fid = H5Fopen(file_name, intent, H5P_DEFAULT)) < 0)
goto error;
ret_value = H5Oopen(fid, obj_name, lapl_id); /* If this fails, our return value will be negative. */
if(H5Fclose(fid) < 0)
diff --git a/test/links.c b/test/links.c
index 2cbb282..61648bf 100644
--- a/test/links.c
+++ b/test/links.c
@@ -1579,7 +1579,7 @@ external_link_root(hid_t fapl)
if(H5Gclose(gid) < 0) TEST_ERROR;
if(H5Fclose(fid)<0) TEST_ERROR;
- /* Open first file again and check on objects created */
+ /* Open first file again with read-only access and check on objects created */
if((fid = H5Fopen(filename1, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR
/* Open objects created through external link */
@@ -1599,13 +1599,26 @@ external_link_root(hid_t fapl)
/* Close first file */
if(H5Fclose(fid)<0) TEST_ERROR;
+ /* Verify that new objects can't be created through a read-only external
+ * link.
+ */
+ if((fid = H5Fopen(filename2, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ H5E_BEGIN_TRY {
+ gid = H5Gcreate(fid, "ext_link/readonly_group", (size_t)0);
+ } H5E_END_TRY
+ if(gid >= 0) TEST_ERROR
+
+ /* Close second file again */
+ if(H5Fclose(fid)<0) TEST_ERROR;
+
PASSED();
return 0;
error:
H5E_BEGIN_TRY {
- H5Fclose (gid2);
- H5Fclose (gid);
+ H5Gclose (gid2);
+ H5Gclose (gid);
H5Fclose (fid);
} H5E_END_TRY;
return -1;
diff --git a/test/tfile.c b/test/tfile.c
index 19772ca..4c6e845 100644
--- a/test/tfile.c
+++ b/test/tfile.c
@@ -347,6 +347,7 @@ test_file_open(void)
size_t parm2; /*file-creation parameters */
unsigned iparm;
unsigned iparm2;
+ unsigned intent;
herr_t ret; /*generic return value */
/*
@@ -360,6 +361,11 @@ test_file_open(void)
fid1 = H5Fopen(FILE2, H5F_ACC_RDWR, H5P_DEFAULT);
CHECK(fid1, FAIL, "H5Fopen");
+ /* Get the intent */
+ ret = H5Fget_intent(fid1, &intent);
+ CHECK(ret, FAIL, "H5Fget_intent");
+ VERIFY(intent, H5F_ACC_RDWR, "H5Fget_intent");
+
/* Get the file-creation template */
tmpl1 = H5Fget_create_plist(fid1);
CHECK(tmpl1, FAIL, "H5Fget_create_plist");
@@ -409,10 +415,19 @@ test_file_open(void)
fid1 = H5Fopen(FILE2, H5F_ACC_RDONLY, fapl_id);
CHECK(fid1, FAIL, "H5Fopen");
+ /* Check the intent */
+ ret = H5Fget_intent(fid1, &intent);
+ CHECK(ret, FAIL, "H5Fget_intent");
+ VERIFY(intent, H5F_ACC_RDONLY, "H5Fget_intent");
+
/* Open dataset */
did = H5Dopen(fid1, F2_DSET);
CHECK(did, FAIL, "H5Dopen");
+ /* Check that the intent works even if NULL is passed in */
+ ret = H5Fget_intent(fid1, NULL);
+ CHECK(ret, FAIL, "H5Fget_intent");
+
/* Close first open */
ret = H5Fclose(fid1);
CHECK(ret, FAIL, "H5Fclose");
@@ -421,6 +436,10 @@ test_file_open(void)
fid2 = H5Fopen(FILE2, H5F_ACC_RDWR, fapl_id);
VERIFY(fid2, FAIL, "H5Fopen");
+ /* Check that the intent fails for an invalid ID */
+ ret = H5Fget_intent(fid1, &intent);
+ VERIFY(ret, FAIL, "H5Fget_intent");
+
/* Close dataset from first open */
ret = H5Dclose(did);
CHECK(ret, FAIL, "H5Dclose");
@@ -859,12 +878,18 @@ test_get_file_id(void)
hid_t datatype_id, dataset_id, dataspace_id, group_id, attr_id;
hid_t plist;
hsize_t dims[F2_RANK];
+ unsigned intent;
herr_t ret;
/* Create a file */
fid = H5Fcreate(FILE4, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
CHECK(fid, FAIL, "H5Fcreate");
+ /* Check the intent */
+ ret = H5Fget_intent(fid, &intent);
+ CHECK(ret, FAIL, "H5Fget_intent");
+ VERIFY(intent, H5F_ACC_RDWR, "H5Fget_intent");
+
/* Test H5Iget_file_id() */
check_file_id(fid, fid);
@@ -1469,6 +1494,7 @@ test_file_open_overlap(void)
hid_t gid;
hid_t sid;
int nobjs; /* # of open objects */
+ unsigned intent;
herr_t ret; /* Generic return value */
/* Output message about test being performed */
@@ -1482,6 +1508,11 @@ test_file_open_overlap(void)
fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT);
CHECK(fid2, FAIL, "H5Fopen");
+ /* Check the intent */
+ ret = H5Fget_intent(fid1, &intent);
+ CHECK(ret, FAIL, "H5Fget_intent");
+ VERIFY(intent, H5F_ACC_RDWR, "H5Fget_intent");
+
/* Create a group in file */
gid = H5Gcreate(fid1, GROUP1, (size_t)0);
CHECK(gid, FAIL, "H5Gcreate");