diff --git a/src/H5Fint.c b/src/H5Fint.c index 883cc00d857..e9817b13048 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -1029,19 +1029,24 @@ H5F_prefix_open_file(bool try, H5F_t **_file, H5F_t *primary_file, H5F_prefix_op * * Purpose: Check the file signature to detect an HDF5 file. * - * Return: true/false/FAIL + * Return: SUCCEED/FAIL *------------------------------------------------------------------------- */ -htri_t -H5F__is_hdf5(const char *name, hid_t fapl_id) +herr_t +H5F__is_hdf5(const char *name, hid_t fapl_id, bool *is_hdf5) { - H5FD_t *lf = NULL; /* Low-level file struct */ - H5F_shared_t *shared = NULL; /* Shared part of file */ - haddr_t sig_addr = HADDR_UNDEF; /* Address of hdf5 file signature */ - htri_t ret_value = FAIL; /* Return value */ + H5FD_t *lf = NULL; /* Low-level file struct */ + H5F_shared_t *shared = NULL; /* Shared part of file */ + haddr_t sig_addr = HADDR_UNDEF; /* Address of hdf5 file signature */ + bool found_hdf5 = false; /* Found an HDF5 file */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE + /* Check output parameter */ + if (!is_hdf5) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid output param"); + /* Open the file */ /* NOTE: This now uses the fapl_id that was passed in, so H5Fis_accessible() * should work with arbitrary VFDs, unlike H5Fis_hdf5(). @@ -1056,20 +1061,24 @@ H5F__is_hdf5(const char *name, hid_t fapl_id) * to read through it will fail so we have to try this first. */ if (NULL != (shared = H5F__sfile_search(lf))) - ret_value = true; + found_hdf5 = true; else { /* The file is an HDF5 file if the HDF5 file signature can be found */ - if (H5FD_locate_signature(lf, &sig_addr) < 0) + if (H5FD_locate_signature(lf, &sig_addr) < 0) { + H5FD_close(lf); HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, FAIL, "error while trying to locate file signature"); - ret_value = (HADDR_UNDEF != sig_addr); + } + found_hdf5 = H5_addr_defined(sig_addr); } -done: /* Close the file */ - if (lf) - if (H5FD_close(lf) < 0 && true == ret_value) - HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close file"); + if (H5FD_close(lf) < 0 && found_hdf5) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close file"); + /* Set output parameter */ + *is_hdf5 = found_hdf5; + +done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5F__is_hdf5() */ diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 3ecff5a28bc..f60841ec55f 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -411,7 +411,7 @@ H5_DLLVAR htri_t ignore_disabled_locks_g; H5_DLL herr_t H5F__post_open(H5F_t *f); H5_DLL H5F_t *H5F__reopen(H5F_t *f); H5_DLL herr_t H5F__flush(H5F_t *f); -H5_DLL htri_t H5F__is_hdf5(const char *name, hid_t fapl_id); +H5_DLL herr_t H5F__is_hdf5(const char *name, hid_t fapl_id, bool *is_hdf5); H5_DLL herr_t H5F__get_file_image(H5F_t *f, void *buf_ptr, size_t buf_len, size_t *image_len); H5_DLL herr_t H5F__get_info(H5F_t *f, H5F_info2_t *finfo); H5_DLL herr_t H5F__format_convert(H5F_t *f); diff --git a/src/H5VLcallback.c b/src/H5VLcallback.c index 196a559608f..1662776ef9c 100644 --- a/src/H5VLcallback.c +++ b/src/H5VLcallback.c @@ -3533,11 +3533,9 @@ H5VL__file_open_find_connector_cb(H5PL_type_t plugin_type, const void *plugin_in H5P_genplist_t *fapl_plist; H5P_genplist_t *fapl_plist_copy; bool is_accessible = false; /* Whether file is accessible */ - ssize_t num_errors = 0; - herr_t status; - hid_t connector_id = H5I_INVALID_HID; - hid_t fapl_id = H5I_INVALID_HID; - herr_t ret_value = H5_ITER_CONT; + hid_t connector_id = H5I_INVALID_HID; + hid_t fapl_id = H5I_INVALID_HID; + herr_t ret_value = H5_ITER_CONT; FUNC_ENTER_PACKAGE @@ -3572,30 +3570,10 @@ H5VL__file_open_find_connector_cb(H5PL_type_t plugin_type, const void *plugin_in vol_cb_args.args.is_accessible.fapl_id = fapl_id; vol_cb_args.args.is_accessible.accessible = &is_accessible; - /* Store current error stack size */ - if ((num_errors = H5Eget_num(H5E_DEFAULT)) < 0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, H5_ITER_ERROR, "can't get current error stack size"); + if (H5VL_file_specific(NULL, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5_ITER_ERROR, "error when checking for accessible HDF5 file"); - /* Check if file is accessible with given VOL connector */ - H5E_BEGIN_TRY - { - status = H5VL_file_specific(NULL, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL); - } - H5E_END_TRY - - if (status < 0) { - ssize_t new_num_errors = 0; - - /* Pop any errors generated by the above call */ - if ((new_num_errors = H5Eget_num(H5E_DEFAULT)) < 0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, H5_ITER_ERROR, "can't get current error stack size"); - if (new_num_errors > num_errors) { - new_num_errors -= num_errors; - if (H5Epop(H5E_DEFAULT, (size_t)new_num_errors) < 0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTRELEASE, H5_ITER_ERROR, "can't sanitize error stack"); - } - } - else if (status == SUCCEED && is_accessible) { + if (is_accessible) { /* If the file was accessible with the current VOL connector, return * the FAPL with that VOL connector set on it. */ diff --git a/src/H5VLconnector.h b/src/H5VLconnector.h index 83a5b087133..4bf082397f8 100644 --- a/src/H5VLconnector.h +++ b/src/H5VLconnector.h @@ -441,6 +441,14 @@ typedef enum H5VL_file_specific_t { H5VL_FILE_FLUSH, /* Flush file */ H5VL_FILE_REOPEN, /* Reopen the file */ H5VL_FILE_IS_ACCESSIBLE, /* Check if a file is accessible */ + /* Note for VOL connector authors: */ + /* Only return an error from this */ + /* callback if it is not possible */ + /* to determine if a file (or */ + /* container) is accessible. */ + /* It is _not_ an error to return */ + /* a 'false' value for the */ + /* 'accessible' argument. */ H5VL_FILE_DELETE, /* Delete a file */ H5VL_FILE_IS_EQUAL /* Check if two files are the same */ } H5VL_file_specific_t; diff --git a/src/H5VLmodule.h b/src/H5VLmodule.h index 125e2a621c9..225ac249b1f 100644 --- a/src/H5VLmodule.h +++ b/src/H5VLmodule.h @@ -362,6 +362,10 @@ * htri_t H5Fis_accessible(const char *container_name, hid_t fapl_id) * \endcode * + * Note also that an error is only returned if it is not possible to determine + * if a file (or container) is accessible. It is not an error to return 'false' + * for whether the file is accessible. + * *

H5Oget_info[1|2]() → H5Oget_info3() and H5Oget_native_info()

* The \ref H5Oget_info1() and \ref H5Oget_info2() family of HDF5 API calls are often * used by user code to obtain information about an object in the file, however diff --git a/src/H5VLnative_file.c b/src/H5VLnative_file.c index cb4841f2595..33a19bfd917 100644 --- a/src/H5VLnative_file.c +++ b/src/H5VLnative_file.c @@ -339,15 +339,10 @@ H5VL__native_file_specific(void *obj, H5VL_file_specific_args_t *args, hid_t H5_ /* H5Fis_accessible */ case H5VL_FILE_IS_ACCESSIBLE: { - htri_t result; - - if ((result = H5F__is_hdf5(args->args.is_accessible.filename, args->args.is_accessible.fapl_id)) < - 0) + if (H5F__is_hdf5(args->args.is_accessible.filename, args->args.is_accessible.fapl_id, + args->args.is_accessible.accessible) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "error in HDF5 file check"); - /* Set 'out' value */ - *args->args.is_accessible.accessible = (bool)result; - break; }