summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Fortner <nfortne2@hdfgroup.org>2012-07-25 21:50:22 (GMT)
committerNeil Fortner <nfortne2@hdfgroup.org>2012-07-25 21:50:22 (GMT)
commitc04144fb39b6d7a489c37e89ac8a0240991026a6 (patch)
tree8f2d927263672bd7b524673a8943d1a982a8a470
parentb5ef63b550d4d1149aebb0c46aebc7df672427aa (diff)
downloadhdf5-c04144fb39b6d7a489c37e89ac8a0240991026a6.zip
hdf5-c04144fb39b6d7a489c37e89ac8a0240991026a6.tar.gz
hdf5-c04144fb39b6d7a489c37e89ac8a0240991026a6.tar.bz2
[svn-r22601] Purpose: Fix HDFFV-5853
Description: When jumping out from between H5_BEGIN_TAG and H5_END_TAG macros using HGOTO_ERROR or HGOTO_DONE, the previous metadata tag is not reset on the dxpl. This could cause problems when, for example, calling H5Ocopy within an H5Literate callback. Added new HGOTO_ERROR_TAG and HGOTO_DONE_TAG macros which must be used in place of the above between H5_BEGIN_TAG and H5_END_TAG. Tested: jam, koala, ostrich (h5committest), durandal
-rw-r--r--release_docs/RELEASE.txt3
-rw-r--r--src/H5Aint.c2
-rw-r--r--src/H5Dchunk.c2
-rw-r--r--src/H5Eprivate.h21
-rw-r--r--src/H5Gnode.c2
-rw-r--r--src/H5Gtest.c14
-rw-r--r--src/H5Gtraverse.c4
-rw-r--r--src/H5O.c2
-rw-r--r--src/H5Oainfo.c4
-rw-r--r--src/H5Ocopy.c2
-rw-r--r--src/H5Olinfo.c2
-rw-r--r--src/H5Oshared.c2
-rw-r--r--src/H5Ostab.c2
-rw-r--r--src/H5Otest.c22
-rw-r--r--src/H5private.h3
-rw-r--r--test/objcopy.c99
16 files changed, 155 insertions, 31 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index 338cc61..aafb18e 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -378,6 +378,9 @@ Bug Fixes since HDF5-1.8.0 release
Library
-------
+ - Fixed an error that could occur when calling H5Ocopy within an
+ H5Literate callback (and possibly other situations).
+ (NAF - 2012/7/25 - HDFFV-5853)
- Fixed an error that would occur when copying an object with attribute
creation order tracked and indexed. (NAF - 2012/3/28 - HDFFV-7762)
- Fixed a bug in H5Ocopy(): When copying an opened object, call the
diff --git a/src/H5Aint.c b/src/H5Aint.c
index 9503a1c..ab9bece 100644
--- a/src/H5Aint.c
+++ b/src/H5Aint.c
@@ -1197,7 +1197,7 @@ H5A_dense_post_copy_file_cb(const H5A_t *attr_src, void *_udata)
/* Insert attribute into dense storage */
if(H5A_dense_insert(udata->file, udata->dxpl_id, udata->ainfo, attr_dst) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, H5_ITER_ERROR, "unable to add to dense storage")
+ HGOTO_ERROR_TAG(H5E_OHDR, H5E_CANTINSERT, H5_ITER_ERROR, "unable to add to dense storage")
/* Reset metadata tag */
H5_END_TAG(H5_ITER_ERROR);
diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c
index dfb4011..93e8869 100644
--- a/src/H5Dchunk.c
+++ b/src/H5Dchunk.c
@@ -4408,7 +4408,7 @@ H5D__chunk_copy_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata)
/* Insert chunk into the destination index */
if((udata->idx_info_dst->storage->ops->insert)(udata->idx_info_dst, &udata_dst) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, H5_ITER_ERROR, "unable to insert chunk into index")
+ HGOTO_ERROR_TAG(H5E_DATASET, H5E_CANTINSERT, H5_ITER_ERROR, "unable to insert chunk into index")
/* Reset metadata tag in dxpl_id */
H5_END_TAG(H5_ITER_ERROR);
diff --git a/src/H5Eprivate.h b/src/H5Eprivate.h
index 2ca48d2..b2ca5eb 100644
--- a/src/H5Eprivate.h
+++ b/src/H5Eprivate.h
@@ -69,6 +69,17 @@ typedef struct H5E_t H5E_t;
}
/*
+ * HGOTO_ERROR_TAG macro, used like HGOTO_ERROR between H5_BEGIN_TAG and
+ * H5_END_TAG statements. Resets the metadata tag before leaving the function.
+ */
+#define HGOTO_ERROR_TAG(maj, min, ret_val, ...) { \
+ if(H5AC_tag(my_dxpl_id, prv_tag, NULL) < 0) \
+ HERROR(H5E_CACHE, H5E_CANTTAG, "unable to apply metadata tag"); \
+ HCOMMON_ERROR(maj, min, __VA_ARGS__); \
+ HGOTO_DONE(ret_val) \
+}
+
+/*
* HGOTO_DONE macro, used to facilitate normal return between a FUNC_ENTER()
* and a FUNC_LEAVE() within a function body. The argument is the return
* value which is assigned to the `ret_value' variable. Control branches to
@@ -77,6 +88,16 @@ typedef struct H5E_t H5E_t;
#define HGOTO_DONE(ret_val) {ret_value = ret_val; goto done;}
/*
+ * HGOTO_DONE_TAG macro, used like HGOTO_DONE between H5_BEGIN_TAG and
+ * H5_END_TAG statements. Resets the metadata tag before leaving the function.
+ */
+#define HGOTO_DONE_TAG(ret_val, err) { \
+ if(H5AC_tag(my_dxpl_id, prv_tag, NULL) < 0) \
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, err, "unable to apply metadata tag") \
+ HGOTO_DONE(ret_val) \
+}
+
+/*
* Macros handling system error messages as described in C standard.
* These macros assume errnum is a valid system error code.
*/
diff --git a/src/H5Gnode.c b/src/H5Gnode.c
index 4d2e045..c0d2885 100644
--- a/src/H5Gnode.c
+++ b/src/H5Gnode.c
@@ -1367,7 +1367,7 @@ H5G__node_copy(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr
if(H5G__stab_insert_real(udata->dst_file, udata->dst_stab, name, &lnk,
obj_type, (obj_type == H5O_TYPE_GROUP ? &gcrt_info : NULL),
dxpl_id) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5_ITER_ERROR, "unable to insert the name")
+ HGOTO_ERROR_TAG(H5E_DATATYPE, H5E_CANTINIT, H5_ITER_ERROR, "unable to insert the name")
/* Reset metadata tag */
H5_END_TAG(H5_ITER_ERROR);
diff --git a/src/H5Gtest.c b/src/H5Gtest.c
index 48aa10b..b39b4ff 100644
--- a/src/H5Gtest.c
+++ b/src/H5Gtest.c
@@ -399,31 +399,31 @@ H5G__new_dense_info_test(hid_t gid, hsize_t *name_count, hsize_t *corder_count)
/* Get the link info */
if(H5G__obj_get_linfo(&(grp->oloc), &linfo, H5AC_dxpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get link info")
+ HGOTO_ERROR_TAG(H5E_SYM, H5E_BADMESG, FAIL, "can't get link info")
/* Check for 'dense' link storage file addresses being defined */
if(!H5F_addr_defined(linfo.fheap_addr))
- HGOTO_DONE(FAIL)
+ HGOTO_DONE_TAG(FAIL, FAIL)
if(!H5F_addr_defined(linfo.name_bt2_addr))
- HGOTO_DONE(FAIL)
+ HGOTO_DONE_TAG(FAIL, FAIL)
/* Open the name index v2 B-tree */
if(NULL == (bt2_name = H5B2_open(grp->oloc.file, H5AC_dxpl_id, linfo.name_bt2_addr, NULL)))
- HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
+ HGOTO_ERROR_TAG(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
/* Retrieve # of records in name index */
if(H5B2_get_nrec(bt2_name, name_count) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from name index")
+ HGOTO_ERROR_TAG(H5E_SYM, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from name index")
/* Check if there is a creation order index */
if(H5F_addr_defined(linfo.corder_bt2_addr)) {
/* Open the creation order index v2 B-tree */
if(NULL == (bt2_corder = H5B2_open(grp->oloc.file, H5AC_dxpl_id, linfo.corder_bt2_addr, NULL)))
- HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for creation order index")
+ HGOTO_ERROR_TAG(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for creation order index")
/* Retrieve # of records in creation order index */
if(H5B2_get_nrec(bt2_corder, corder_count) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from creation order index")
+ HGOTO_ERROR_TAG(H5E_SYM, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from creation order index")
} /* end if */
else
*corder_count = 0;
diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c
index aff87f8..1efc521 100644
--- a/src/H5Gtraverse.c
+++ b/src/H5Gtraverse.c
@@ -855,7 +855,7 @@ H5G_traverse(const H5G_loc_t *loc, const char *name, unsigned target, H5G_traver
if(H5P_get(lapl, H5L_ACS_NLINKS_NAME, &nlinks) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get number of links")
} /* end else */
-
+
/* Set up invalid tag. This is a precautionary step only. Setting an invalid
tag here will ensure that no metadata accessed while doing the traversal
is given an improper tag, unless another one is specifically set up
@@ -866,7 +866,7 @@ H5G_traverse(const H5G_loc_t *loc, const char *name, unsigned target, H5G_traver
/* Go perform "real" traversal */
if(H5G_traverse_real(loc, name, target, &nlinks, op, op_data, lapl_id, dxpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "internal path traversal failed")
+ HGOTO_ERROR_TAG(H5E_SYM, H5E_NOTFOUND, FAIL, "internal path traversal failed")
/* Reset tag after traversal */
H5_END_TAG(FAIL);
diff --git a/src/H5O.c b/src/H5O.c
index 104a9ae..5050941 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -1258,7 +1258,7 @@ H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, size_t initial_rc,
/* Cache object header */
if(H5AC_insert_entry(f, dxpl_id, H5AC_OHDR, oh_addr, oh, insert_flags) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to cache object header")
+ HGOTO_ERROR_TAG(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to cache object header")
oh = NULL;
/* Reset metadata tag in dxpl_id */
diff --git a/src/H5Oainfo.c b/src/H5Oainfo.c
index b207ea2..ad99be0 100644
--- a/src/H5Oainfo.c
+++ b/src/H5Oainfo.c
@@ -428,12 +428,12 @@ H5O_ainfo_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst,
if(H5F_addr_defined(ainfo_src->fheap_addr)) {
/* copy dense attribute */
-
+
/* Set copied metadata tag */
H5_BEGIN_TAG(dxpl_id, H5AC__COPIED_TAG, NULL);
if(H5A_dense_create(file_dst, dxpl_id, ainfo_dst) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to create dense storage for attributes")
+ HGOTO_ERROR_TAG(H5E_OHDR, H5E_CANTINIT, NULL, "unable to create dense storage for attributes")
/* Reset metadata tag */
H5_END_TAG(NULL);
diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c
index 7b812ec..b22eeb0 100644
--- a/src/H5Ocopy.c
+++ b/src/H5Ocopy.c
@@ -862,7 +862,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out*/,
/* Insert destination object header in cache */
if(H5AC_insert_entry(oloc_dst->file, dxpl_id, H5AC_OHDR, oloc_dst->addr, oh_dst, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to cache object header")
+ HGOTO_ERROR_TAG(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to cache object header")
oh_dst = NULL;
inserted = TRUE;
diff --git a/src/H5Olinfo.c b/src/H5Olinfo.c
index e96483a..5c0ed53 100644
--- a/src/H5Olinfo.c
+++ b/src/H5Olinfo.c
@@ -474,7 +474,7 @@ H5O_linfo_post_copy_file_cb(const H5O_link_t *src_lnk, void *_udata)
/* Insert the new object in the destination file's group */
/* (Doesn't increment the link count - that's already been taken care of for hard links) */
if(H5G__dense_insert(udata->dst_oloc->file, udata->dxpl_id, udata->dst_linfo, &dst_lnk) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, H5_ITER_ERROR, "unable to insert destination link")
+ HGOTO_ERROR_TAG(H5E_OHDR, H5E_CANTINSERT, H5_ITER_ERROR, "unable to insert destination link")
/* Reset metadata tag in dxpl_id */
H5_END_TAG(FAIL);
diff --git a/src/H5Oshared.c b/src/H5Oshared.c
index c29e2c7..e4a51ee 100644
--- a/src/H5Oshared.c
+++ b/src/H5Oshared.c
@@ -622,7 +622,7 @@ H5O_shared_copy_file(H5F_t *file_src, H5F_t *file_dst,
H5_BEGIN_TAG(dxpl_id, H5AC__COPIED_TAG, FAIL);
if(H5SM_try_share(file_dst, dxpl_id, NULL, H5SM_DEFER, mesg_type->id, _native_dst, mesg_flags) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to determine if message should be shared")
+ HGOTO_ERROR_TAG(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to determine if message should be shared")
/* Reset metadata tag */
H5_END_TAG(FAIL);
diff --git a/src/H5Ostab.c b/src/H5Ostab.c
index d5f5f86..47bd9fc 100644
--- a/src/H5Ostab.c
+++ b/src/H5Ostab.c
@@ -336,7 +336,7 @@ H5O_stab_copy_file(H5F_t *file_src, void *native_src, H5F_t *file_dst,
/* Create components of symbol table message */
if(H5G__stab_create_components(file_dst, stab_dst, size_hint, dxpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't create symbol table components")
+ HGOTO_ERROR_TAG(H5E_SYM, H5E_CANTINIT, NULL, "can't create symbol table components")
/* Reset metadata tag */
H5_END_TAG(NULL);
diff --git a/src/H5Otest.c b/src/H5Otest.c
index ca1b426..5802904 100644
--- a/src/H5Otest.c
+++ b/src/H5Otest.c
@@ -193,13 +193,13 @@ H5O_is_attr_empty_test(hid_t oid)
if(H5F_addr_defined(ainfo.fheap_addr)) {
/* Check for any messages in object header */
HDassert(nattrs == 0);
-
+
/* Set metadata tag in dxpl_id */
H5_BEGIN_TAG(H5AC_ind_dxpl_id, loc->addr, FAIL);
/* Open the name index v2 B-tree */
if(NULL == (bt2_name = H5B2_open(loc->file, H5AC_ind_dxpl_id, ainfo.name_bt2_addr, NULL)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
+ HGOTO_ERROR_TAG(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
/* Reset metadata tag in dxpl_id */
H5_END_TAG(FAIL);
@@ -292,7 +292,7 @@ H5O_num_attrs_test(hid_t oid, hsize_t *nattrs)
/* Open the name index v2 B-tree */
if(NULL == (bt2_name = H5B2_open(loc->file, H5AC_ind_dxpl_id, ainfo.name_bt2_addr, NULL)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
+ HGOTO_ERROR_TAG(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
/* Reset metadata tag in dxpl_id */
H5_END_TAG(FAIL);
@@ -362,39 +362,39 @@ H5O_attr_dense_info_test(hid_t oid, hsize_t *name_count, hsize_t *corder_count)
/* Get the object header */
if(NULL == (oh = H5O_protect(loc, H5AC_ind_dxpl_id, H5AC_READ)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
+ HGOTO_ERROR_TAG(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
/* Check for attribute info stored */
ainfo.fheap_addr = HADDR_UNDEF;
if(oh->version > H5O_VERSION_1) {
/* Check for (& retrieve if available) attribute info */
if(H5A_get_ainfo(loc->file, H5AC_ind_dxpl_id, oh, &ainfo) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message")
+ HGOTO_ERROR_TAG(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message")
} /* end if */
/* Check for 'dense' attribute storage file addresses being defined */
if(!H5F_addr_defined(ainfo.fheap_addr))
- HGOTO_DONE(FAIL)
+ HGOTO_DONE_TAG(FAIL, FAIL)
if(!H5F_addr_defined(ainfo.name_bt2_addr))
- HGOTO_DONE(FAIL)
+ HGOTO_DONE_TAG(FAIL, FAIL)
/* Open the name index v2 B-tree */
if(NULL == (bt2_name = H5B2_open(loc->file, H5AC_ind_dxpl_id, ainfo.name_bt2_addr, NULL)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
+ HGOTO_ERROR_TAG(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
/* Retrieve # of records in name index */
if(H5B2_get_nrec(bt2_name, name_count) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from name index")
+ HGOTO_ERROR_TAG(H5E_OHDR, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from name index")
/* Check if there is a creation order index */
if(H5F_addr_defined(ainfo.corder_bt2_addr)) {
/* Open the creation order index v2 B-tree */
if(NULL == (bt2_corder = H5B2_open(loc->file, H5AC_ind_dxpl_id, ainfo.corder_bt2_addr, NULL)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for creation order index")
+ HGOTO_ERROR_TAG(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for creation order index")
/* Retrieve # of records in creation order index */
if(H5B2_get_nrec(bt2_corder, corder_count) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from creation order index")
+ HGOTO_ERROR_TAG(H5E_OHDR, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from creation order index")
} /* end if */
else
*corder_count = 0;
diff --git a/src/H5private.h b/src/H5private.h
index 39ccb52..d30298f 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -2291,7 +2291,8 @@ func_init_failed: \
/* Close Function */ \
}
-/* Macro to begin/end tagging (when FUNC_ENTER_*TAG macros are insufficient) */
+/* Macro to begin/end tagging (when FUNC_ENTER_*TAG macros are insufficient).
+ * Make sure to use HGOTO_ERROR_TAG and HGOTO_DONE_TAG between these macros! */
#define H5_BEGIN_TAG(dxpl, tag, err) { \
haddr_t prv_tag = HADDR_UNDEF; \
hid_t my_dxpl_id = dxpl; \
diff --git a/test/objcopy.c b/test/objcopy.c
index ce0f3d3..6b56b66 100644
--- a/test/objcopy.c
+++ b/test/objcopy.c
@@ -11452,6 +11452,104 @@ error:
/*-------------------------------------------------------------------------
+ * Function: test_copy_iterate
+ *
+ * Purpose: Tests iterating over objects in the root group, copying
+ * all of them.
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Neil Fortner
+ * Thursday, July 12, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+test_copy_iterate_cb(hid_t loc_id, const char *name,
+ const H5L_info_t UNUSED *link_info, void *op_data)
+{
+ hid_t dst_loc_id = *((hid_t *)op_data);
+
+ if(H5Ocopy(loc_id, name, dst_loc_id, name, H5P_DEFAULT, H5P_DEFAULT) < 0)
+ TEST_ERROR
+
+ return(H5_ITER_CONT);
+
+error:
+ return(H5_ITER_ERROR);
+} /* end test_copy_iterate_cb */
+
+static int
+test_copy_iterate(hid_t fcpl_src, hid_t fcpl_dst, hid_t src_fapl, hid_t dst_fapl)
+{
+ hid_t fid1 = -1, fid2 = -1; /* File IDs */
+ hid_t gid = -1; /* Group ID */
+ int i;
+ char grp_name[8];
+ char src_filename[NAME_BUF_SIZE];
+ char dst_filename[NAME_BUF_SIZE];
+
+ TESTING("H5Ocopy(): inside H5Literate() callback");
+
+ /* Initialize the filenames */
+ h5_fixname(FILENAME[0], src_fapl, src_filename, sizeof src_filename);
+ h5_fixname(FILENAME[1], src_fapl, dst_filename, sizeof dst_filename);
+
+ /* Reset file address checking info */
+ addr_reset();
+
+ /* Create source file */
+ if((fid1 = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, src_fapl)) < 0)
+ TEST_ERROR
+
+ /* Create groups */
+ for(i=0; i<9; i++) {
+ HDsnprintf(grp_name, sizeof(grp_name), "grp%d", i);
+ if((gid = H5Gcreate2(fid1, grp_name, H5P_DEFAULT, H5P_DEFAULT,
+ H5P_DEFAULT)) < 0)
+ TEST_ERROR
+ if(H5Gclose(gid) < 0)
+ TEST_ERROR
+ } /* end for */
+
+ /* Create destination file */
+ if((fid2 = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, dst_fapl)) < 0)
+ TEST_ERROR
+
+ /* Close files */
+ if(H5Fclose(fid1) < 0) TEST_ERROR
+ if(H5Fclose(fid2) < 0) TEST_ERROR
+
+ /* Reopen files */
+ if((fid1 = H5Fopen(src_filename, H5F_ACC_RDWR, src_fapl)) < 0) TEST_ERROR
+ if((fid2 = H5Fopen(dst_filename, H5F_ACC_RDWR, dst_fapl)) < 0) TEST_ERROR
+
+ /* Iterate over links in the root group, copying each object */
+ if((gid = H5Gopen2(fid1, "/", H5P_DEFAULT)) < 0) TEST_ERROR
+ if(H5Literate(gid, H5_INDEX_NAME, H5_ITER_INC, NULL, test_copy_iterate_cb,
+ &fid2) < 0)
+ TEST_ERROR
+
+ /* Close */
+ if(H5Gclose(gid) < 0) TEST_ERROR
+ if(H5Fclose(fid1) < 0) TEST_ERROR
+ if(H5Fclose(fid2) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Gclose(gid);
+ H5Fclose(fid1);
+ H5Fclose(fid2);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_iterate */
+
+
+/*-------------------------------------------------------------------------
* Function: test_copy_option
*
* Purpose: Create a group in SRC file and copy it to DST file
@@ -12289,6 +12387,7 @@ main(void)
nerrors += test_copy_same_file_named_datatype(fcpl_src, src_fapl);
nerrors += test_copy_old_layout(fcpl_dst, dst_fapl);
nerrors += test_copy_null_ref(fcpl_src, fcpl_dst, src_fapl, dst_fapl);
+ nerrors += test_copy_iterate(fcpl_src, fcpl_dst, src_fapl, dst_fapl);
}
/* TODO: not implemented