From 9edac8a668f823aa7a60a97e4332216619609ba5 Mon Sep 17 00:00:00 2001 From: James Laird Date: Wed, 23 Aug 2006 19:52:21 -0500 Subject: [svn-r12623] Added H5Fget_intent() function to get the "intent" of a file (read/write or read-only). Added this to external links, so that external files are opened with the same intent as the source file. Added tests. --- src/H5F.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/H5Fpublic.h | 1 + src/H5Lexternal.c | 11 ++++++++++- test/links.c | 19 ++++++++++++++++--- test/tfile.c | 31 +++++++++++++++++++++++++++++++ 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"); -- cgit v0.12