From c04144fb39b6d7a489c37e89ac8a0240991026a6 Mon Sep 17 00:00:00 2001 From: Neil Fortner Date: Wed, 25 Jul 2012 16:50:22 -0500 Subject: [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 --- release_docs/RELEASE.txt | 3 ++ src/H5Aint.c | 2 +- src/H5Dchunk.c | 2 +- src/H5Eprivate.h | 21 ++++++++++ src/H5Gnode.c | 2 +- src/H5Gtest.c | 14 +++---- src/H5Gtraverse.c | 4 +- src/H5O.c | 2 +- src/H5Oainfo.c | 4 +- src/H5Ocopy.c | 2 +- src/H5Olinfo.c | 2 +- src/H5Oshared.c | 2 +- src/H5Ostab.c | 2 +- src/H5Otest.c | 22 +++++------ src/H5private.h | 3 +- test/objcopy.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++ 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 -- cgit v0.12