diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/H5.c | 10 | ||||
-rw-r--r-- | src/H5Dchunk.c | 102 | ||||
-rw-r--r-- | src/H5Dio.c | 169 | ||||
-rw-r--r-- | src/H5Dprivate.h | 3 | ||||
-rw-r--r-- | src/H5Dpublic.h | 19 | ||||
-rw-r--r-- | src/H5Dscatgath.c | 204 | ||||
-rw-r--r-- | src/H5FDcore.c | 558 | ||||
-rw-r--r-- | src/H5FDlog.c | 412 | ||||
-rw-r--r-- | src/H5FDmpi.c | 5 | ||||
-rw-r--r-- | src/H5FDmpi.h | 53 | ||||
-rw-r--r-- | src/H5FDmpio.c | 5 | ||||
-rw-r--r-- | src/H5FDmpio.h | 3 | ||||
-rw-r--r-- | src/H5FDmpiposix.c | 62 | ||||
-rw-r--r-- | src/H5FDmpiposix.h | 3 | ||||
-rw-r--r-- | src/H5FDmulti.c | 102 | ||||
-rw-r--r-- | src/H5FDprivate.h | 41 | ||||
-rw-r--r-- | src/H5FDsec2.c | 381 | ||||
-rw-r--r-- | src/H5FDstdio.c | 58 | ||||
-rw-r--r-- | src/H5Fmpi.c | 1 | ||||
-rw-r--r-- | src/H5Gint.c | 4 | ||||
-rw-r--r-- | src/H5Gname.c | 55 | ||||
-rw-r--r-- | src/H5Gtest.c | 2 | ||||
-rw-r--r-- | src/H5HFdbg.c | 14 | ||||
-rw-r--r-- | src/H5Lexternal.c | 47 | ||||
-rw-r--r-- | src/H5Ocopy.c | 2 | ||||
-rw-r--r-- | src/H5Oname.c | 12 | ||||
-rw-r--r-- | src/H5Pdxpl.c | 38 | ||||
-rw-r--r-- | src/H5T.c | 4 | ||||
-rw-r--r-- | src/H5config.h.in | 3 | ||||
-rw-r--r-- | src/H5private.h | 73 | ||||
-rw-r--r-- | src/H5public.h | 4 | ||||
-rw-r--r-- | src/H5system.c | 536 | ||||
-rw-r--r-- | src/Makefile.in | 4 |
34 files changed, 1705 insertions, 1286 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3cbfe7e..31b7f3d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.8.6) +cmake_minimum_required (VERSION 2.8.10) PROJECT (HDF5_SRC C CXX) #----------------------------------------------------------------------------- @@ -714,14 +714,14 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum) if (!disable_version_check){ /* - *verify if H5_VERS_INFO is consistent with the other version information. - *Check only the first sizeof(lib_str) char. Assume the information - *will fit within this size or enough significance. + * Verify if H5_VERS_INFO is consistent with the other version information. + * Check only the first sizeof(lib_str) char. Assume the information + * will fit within this size or enough significance. */ - sprintf(lib_str, "HDF5 library version: %d.%d.%d", + HDsnprintf(lib_str, sizeof(lib_str), "HDF5 library version: %d.%d.%d", H5_VERS_MAJOR, H5_VERS_MINOR, H5_VERS_RELEASE); if(*substr) { - HDstrcat(lib_str, "-"); + HDstrncat(lib_str, "-", 1); HDstrncat(lib_str, substr, (sizeof(lib_str) - HDstrlen(lib_str)) - 1); } /* end if */ if (HDstrcmp(lib_str, H5_lib_vers_info_g)){ diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index 0471ccd..fb4f35f 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -287,6 +287,108 @@ H5FL_DEFINE(H5D_chunk_info_t); /* Declare a free list to manage the chunk sequence information */ H5FL_BLK_DEFINE_STATIC(chunk); + +/*------------------------------------------------------------------------- + * Function: H5D__chunk_direct_write + * + * Purpose: Internal routine to write a chunk + * directly into the file. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Raymond Lu + * 30 July 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D__chunk_direct_write(const H5D_t *dset, hid_t dxpl_id, uint32_t filters, hsize_t *offset, + size_t data_size, const void *buf) +{ + const H5O_layout_t *layout = &(dset->shared->layout); /* Dataset layout */ + H5D_chunk_ud_t udata; /* User data for querying chunk info */ + hsize_t chunk_idx; + H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */ + H5D_dxpl_cache_t *dxpl_cache = &_dxpl_cache; /* Data transfer property cache */ + const H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk); /*raw data chunk cache */ + int space_ndims; /* Dataset's space rank */ + hsize_t space_dim[H5O_LAYOUT_NDIMS]; /* Dataset's dataspace dimensions */ + H5FD_t *lf; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC_TAG(dxpl_id, dset->oloc.addr, FAIL) + + /* Allocate data space and initialize it if it hasn't been. */ + if(!(*dset->shared->layout.ops->is_space_alloc)(&dset->shared->layout.storage)) { + /* Allocate storage */ + if(H5D__alloc_storage(dset, dxpl_id, H5D_ALLOC_WRITE, FALSE, NULL) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize storage") + } /* end if */ + + + /* Retrieve the dataset dimensions */ + if((space_ndims = H5S_get_simple_extent_dims(dset->shared->space, space_dim, NULL)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get simple dataspace info") + + /* Calculate the index of this chunk */ + if(H5V_chunk_index((unsigned)space_ndims, offset, + layout->u.chunk.dim, layout->u.chunk.down_chunks, &chunk_idx) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't get chunk index") + + /* Find out the file address of the chunk */ + if(H5D__chunk_lookup(dset, dxpl_id, offset, chunk_idx, + &udata) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address") + + udata.filter_mask = filters; + + /* Check if the chunk needs to be 'inserted' (could exist already and + * the 'insert' operation could resize it) + */ + { + H5D_chk_idx_info_t idx_info; /* Chunked index info */ + + /* Compose chunked index info struct */ + idx_info.f = dset->oloc.file; + idx_info.dxpl_id = dxpl_id; + idx_info.pline = &(dset->shared->dcpl_cache.pline); + idx_info.layout = &(dset->shared->layout.u.chunk); + idx_info.storage = &(dset->shared->layout.storage.u.chunk); + + /* Set up the size of chunk for user data */ + udata.nbytes = data_size; + + /* Create the chunk it if it doesn't exist, or reallocate the chunk + * if its size changed. + */ + if((dset->shared->layout.storage.u.chunk.ops->insert)(&idx_info, &udata) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "unable to insert/resize chunk") + + /* Make sure the address of the chunk is returned. */ + if(!H5F_addr_defined(udata.addr)) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "chunk address isn't defined") + } /* end if */ + + /* Fill the DXPL cache values for later use */ + if(H5D__get_dxpl_cache(dxpl_id, &dxpl_cache) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't fill dxpl cache") + + /* Evict the entry from the cache if present, but do not flush + * it to disk */ + if(UINT_MAX != udata.idx_hint) { + if(H5D__chunk_cache_evict(dset, dxpl_id, dxpl_cache, + rdcc->slot[udata.idx_hint], FALSE) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTREMOVE, FAIL, "unable to evict chunk") + } /* end if */ + + /* Write the data to the file */ + if(H5F_block_write(dset->oloc.file, H5FD_MEM_DRAW, udata.addr, data_size, dxpl_id, buf) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to write raw data to file") + + +done: + FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL) +} /*------------------------------------------------------------------------- diff --git a/src/H5Dio.c b/src/H5Dio.c index 1bd6dae..df1c4a3 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -28,6 +28,8 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Sprivate.h" /* Dataspace */ #ifdef H5_HAVE_PARALLEL /* Remove this if H5R_DATASET_REGION is no longer used in this file */ @@ -56,6 +58,8 @@ static herr_t H5D__read(H5D_t *dataset, hid_t mem_type_id, static herr_t H5D__write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, const H5S_t *file_space, hid_t dset_xfer_plist, const void *buf); +static herr_t H5D__pre_write(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, + hid_t file_space_id, hid_t dxpl_id, const void *buf); /* Setup/teardown routines */ static herr_t H5D__ioinfo_init(H5D_t *dset, const H5D_dxpl_cache_t *dxpl_cache, @@ -136,6 +140,10 @@ H5Dread(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") if(NULL == dset->oloc.file) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") + + if(mem_space_id < 0 || file_space_id < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space") + if(H5S_ALL != mem_space_id) { if(NULL == (mem_space = (const H5S_t *)H5I_object_verify(mem_space_id, H5I_DATASPACE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space") @@ -213,37 +221,51 @@ herr_t H5Dwrite(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id, const void *buf) { - H5D_t *dset = NULL; - const H5S_t *mem_space = NULL; - const H5S_t *file_space = NULL; - char fake_char; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "iiiii*x", dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf); + if(!dset_id) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") + + if(H5D__pre_write(dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't prepare for writing data") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Dwrite() */ + + +/*------------------------------------------------------------------------- + * Function: H5D__pre_write + * + * Purpose: Preparation for writing data. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Raymond Lu + * 2 November 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D__pre_write(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, + hid_t file_space_id, hid_t dxpl_id, const void *buf) +{ + H5D_t *dset = NULL; + H5P_genplist_t *plist; /* Property list pointer */ + hbool_t direct_write = FALSE; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + /* check arguments */ if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") if(NULL == dset->oloc.file) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") - if(H5S_ALL != mem_space_id) { - if(NULL == (mem_space = (const H5S_t *)H5I_object_verify(mem_space_id, H5I_DATASPACE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space") - - /* Check for valid selection */ - if(H5S_SELECT_VALID(mem_space) != TRUE) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "memory selection+offset not within extent") - } /* end if */ - if(H5S_ALL != file_space_id) { - if(NULL == (file_space = (const H5S_t *)H5I_object_verify(file_space_id, H5I_DATASPACE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space") - - /* Check for valid selection */ - if(H5S_SELECT_VALID(file_space) != TRUE) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "file selection+offset not within extent") - } /* end if */ + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") /* Get the default dataset transfer property list if the user didn't provide one */ if(H5P_DEFAULT == dxpl_id) @@ -251,23 +273,102 @@ H5Dwrite(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, else if(TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms") - if(!buf && (NULL == file_space || H5S_GET_SELECT_NPOINTS(file_space) != 0)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no output buffer") - /* If the buffer is nil, and 0 element is selected, make a fake buffer. - * This is for some MPI package like ChaMPIon on NCSA's tungsten which - * doesn't support this feature. - */ - if(!buf) - buf = &fake_char; + /* Get the dataset transfer property list */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list") + + if(H5P_get(plist, H5D_XFER_DIRECT_CHUNK_WRITE_FLAG_NAME, &direct_write) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "error getting flag for direct chunk write") + + /* Direct chunk write */ + if(direct_write) { + uint32_t direct_filters = 0; + hsize_t *direct_offset; + size_t direct_datasize = 0; + int ndims = 0; + hsize_t dims[H5O_LAYOUT_NDIMS]; + hsize_t internal_offset[H5O_LAYOUT_NDIMS]; + int i; + + if(H5D_CHUNKED != dset->shared->layout.type) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a chunked dataset") + + if(H5P_get(plist, H5D_XFER_DIRECT_CHUNK_WRITE_FILTERS_NAME, &direct_filters) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "error getting filter info for direct chunk write") + + if(H5P_get(plist, H5D_XFER_DIRECT_CHUNK_WRITE_OFFSET_NAME, &direct_offset) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "error getting offset info for direct chunk write") + + if(H5P_get(plist, H5D_XFER_DIRECT_CHUNK_WRITE_DATASIZE_NAME, &direct_datasize) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "error getting data size for direct chunk write") + + /* The library's chunking code requires the offset terminates with a zero. So transfer the + * offset array to an internal offset array */ + if((ndims = H5S_get_simple_extent_dims(dset->shared->space, dims, NULL)) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't retrieve dataspace extent dims") + + for(i=0; i<ndims; i++) { + /* Make sure the offset doesn't exceed the dataset's dimensions */ + if(direct_offset[i] > dims[i]) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "offset exceeds dimensions of dataset") + + /* Make sure the offset fall right on a chunk's boundary */ + if(direct_offset[i] % dset->shared->layout.u.chunk.dim[i]) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "offset doesn't fall on chunks's boundary") + + internal_offset[i] = direct_offset[i]; + } + + /* Terminate the offset with a zero */ + internal_offset[ndims] = 0; + + /* write raw data */ + if(H5D__chunk_direct_write(dset, dxpl_id, direct_filters, internal_offset, direct_datasize, buf) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write chunk directly") + } else { /* Normal write */ + const H5S_t *mem_space = NULL; + const H5S_t *file_space = NULL; + char fake_char; + + if(mem_space_id < 0 || file_space_id < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space") - /* write raw data */ - if(H5D__write(dset, mem_type_id, mem_space, file_space, dxpl_id, buf) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data") + if(H5S_ALL != mem_space_id) { + if(NULL == (mem_space = (const H5S_t *)H5I_object_verify(mem_space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space") + + /* Check for valid selection */ + if(H5S_SELECT_VALID(mem_space) != TRUE) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "memory selection+offset not within extent") + } /* end if */ + if(H5S_ALL != file_space_id) { + if(NULL == (file_space = (const H5S_t *)H5I_object_verify(file_space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space") + + /* Check for valid selection */ + if(H5S_SELECT_VALID(file_space) != TRUE) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "file selection+offset not within extent") + } /* end if */ + + if(!buf && (NULL == file_space || H5S_GET_SELECT_NPOINTS(file_space) != 0)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no output buffer") + + /* If the buffer is nil, and 0 element is selected, make a fake buffer. + * This is for some MPI package like ChaMPIon on NCSA's tungsten which + * doesn't support this feature. + */ + if(!buf) + buf = &fake_char; + + /* write raw data */ + if(H5D__write(dset, mem_type_id, mem_space, file_space, dxpl_id, buf) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data") + } done: - FUNC_LEAVE_API(ret_value) -} /* end H5Dwrite() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__pre_write() */ /*------------------------------------------------------------------------- diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index ae55c44..2f0cceb 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -175,5 +175,8 @@ H5_DLL herr_t H5D_chunk_idx_reset(H5O_storage_chunk_t *storage, hbool_t reset_ad H5_DLL herr_t H5D_btree_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, int fwidth, unsigned ndims); +H5_DLL herr_t H5D__chunk_direct_write(const H5D_t *dset, hid_t dxpl_id, uint32_t filters, + hsize_t *offset, size_t data_size, const void *buf); + #endif /* _H5Dprivate_H */ diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h index a96755a..9a97627 100644 --- a/src/H5Dpublic.h +++ b/src/H5Dpublic.h @@ -37,6 +37,12 @@ /* Bit flags for the H5Pset_chunk_opts() and H5Pget_chunk_opts() */ #define H5D_CHUNK_DONT_FILTER_PARTIAL_CHUNKS (0x0002u) +/* Property names for H5LTDdirect_chunk_write */ +#define H5D_XFER_DIRECT_CHUNK_WRITE_FLAG_NAME "direct_chunk_flag" +#define H5D_XFER_DIRECT_CHUNK_WRITE_FILTERS_NAME "direct_chunk_filters" +#define H5D_XFER_DIRECT_CHUNK_WRITE_OFFSET_NAME "direct_chunk_offset" +#define H5D_XFER_DIRECT_CHUNK_WRITE_DATASIZE_NAME "direct_chunk_datasize" + /*******************/ /* Public Typedefs */ /*******************/ @@ -109,6 +115,15 @@ extern "C" { typedef herr_t (*H5D_operator_t)(void *elem, hid_t type_id, unsigned ndim, const hsize_t *point, void *operator_data); +/* Define the operator function pointer for H5Dscatter() */ +typedef herr_t (*H5D_scatter_func_t)(void **src_buf/*out*/, + size_t *src_buf_bytes_used/*out*/, + void *op_data); + +/* Define the operator function pointer for H5Dgather() */ +typedef herr_t (*H5D_gather_func_t)(const void *dst_buf, + size_t dst_buf_bytes_used, void *op_data); + H5_DLL hid_t H5Dcreate2(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, hid_t lcpl_id, hid_t dcpl_id, hid_t dapl_id); H5_DLL hid_t H5Dcreate_anon(hid_t file_id, hid_t type_id, hid_t space_id, @@ -135,6 +150,10 @@ H5_DLL herr_t H5Dfill(const void *fill, hid_t fill_type, void *buf, H5_DLL herr_t H5Dset_extent(hid_t dset_id, const hsize_t size[]); H5_DLL herr_t H5Dflush(hid_t dset_id); H5_DLL herr_t H5Drefresh(hid_t dset_id); +H5_DLL herr_t H5Dscatter(H5D_scatter_func_t op, void *op_data, hid_t type_id, + hid_t dst_space_id, void *dst_buf); +H5_DLL herr_t H5Dgather(hid_t src_space_id, void *src_buf, hid_t type_id, + size_t dst_buf_size, void *dst_buf, H5D_gather_func_t op, void *op_data); H5_DLL herr_t H5Ddebug(hid_t dset_id); /* Symbols defined for compatibility with previous versions of the HDF5 API. diff --git a/src/H5Dscatgath.c b/src/H5Dscatgath.c index 49b6132..60a8800 100644 --- a/src/H5Dscatgath.c +++ b/src/H5Dscatgath.c @@ -27,6 +27,7 @@ #include "H5Dpkg.h" /* Dataset functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5FLprivate.h" /* Free Lists */ +#include "H5Iprivate.h" /* IDs */ /****************/ @@ -361,7 +362,7 @@ done: * copies them into the gather buffer TGATH_BUF. * Each element is ELMT_SIZE bytes and arranged in application * memory according to SPACE. - * The caller is requesting that at most NELMTS be gathered. + * The caller is requesting that exactly NELMTS be gathered. * * Return: Success: Number of elements copied. * Failure: 0 @@ -899,3 +900,204 @@ H5D__compound_opt_write(size_t nelmts, const H5D_type_info_t *type_info) FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5D__compound_opt_write() */ + +/*------------------------------------------------------------------------- + * Function: H5Dscatter + * + * Purpose: Scatters data provided by the callback op to the + * destination buffer dst_buf, where the dimensions of + * dst_buf and the selection to be scattered to are specified + * by the dataspace dst_space_id. The type of the data to be + * scattered is specified by type_id. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * 14 Jan 2013 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Dscatter(H5D_scatter_func_t op, void *op_data, hid_t type_id, + hid_t dst_space_id, void *dst_buf) +{ + H5T_t *type; /* Datatype */ + H5S_t *dst_space; /* Dataspace */ + H5S_sel_iter_t iter; /* Selection iteration info*/ + hbool_t iter_init = FALSE; /* Selection iteration info has been initialized */ + void *src_buf = NULL; /* Source (contiguous) data buffer */ + size_t src_buf_nbytes = 0; /* Size of src_buf */ + size_t type_size; /* Datatype element size */ + hssize_t nelmts; /* Number of remaining elements in selection */ + size_t nelmts_scatter = 0; /* Number of elements to scatter to dst_buf */ + H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */ + H5D_dxpl_cache_t *dxpl_cache = &_dxpl_cache; /* Data transfer property cache */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE5("e", "x*xii*x", op, op_data, type_id, dst_space_id, dst_buf); + + /* Check args */ + if(op == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid callback function pointer") + if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") + if(NULL == (dst_space= (H5S_t *)H5I_object_verify(dst_space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") + if(dst_buf == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no destination buffer provided") + + /* Fill the DXPL cache values for later use */ + if(H5D__get_dxpl_cache(H5P_DATASET_XFER_DEFAULT, &dxpl_cache) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't fill dxpl cache") + + /* Get datatype element size */ + if(0 == (type_size = H5T_GET_SIZE(type))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get datatype size") + + /* Get number of elements in dataspace */ + if((nelmts = (hssize_t)H5S_GET_SELECT_NPOINTS(dst_space)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "unable to get number of elements in selection") + + /* Initialize selection iterator */ + if(H5S_select_iter_init(&iter, dst_space, type_size) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize selection iterator information") + iter_init = TRUE; + + /* Loop until all data has been scattered */ + while(nelmts > 0) { + /* Make callback to retrieve data */ + if(op(&src_buf, &src_buf_nbytes, op_data) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CALLBACK, FAIL, "callback operator returned failure") + + /* Calculate number of elements */ + nelmts_scatter = src_buf_nbytes / type_size; + + /* Check callback results */ + if(!src_buf) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "callback did not return a buffer") + if(src_buf_nbytes == 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "callback returned a buffer size of 0") + if(src_buf_nbytes % type_size) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "buffer size is not a multiple of datatype size") + if(nelmts_scatter > (size_t)nelmts) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "callback returned more elements than in selection") + + /* Scatter data */ + if(H5D__scatter_mem(src_buf, dst_space, &iter, nelmts_scatter, dxpl_cache, dst_buf) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "scatter failed") + + nelmts -= (hssize_t)nelmts_scatter; + } /* end while */ + +done: + /* Release selection iterator */ + if(iter_init) { + if(H5S_SELECT_ITER_RELEASE(&iter) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't release selection iterator") + } /* end if */ + + FUNC_LEAVE_API(ret_value) +} /* H5Dscatter() */ + + +/*------------------------------------------------------------------------- + * Function: H5Dgather + * + * Purpose: Gathers data provided from the source buffer src_buf to + * contiguous buffer dst_buf, then calls the callback op. + * The dimensions of src_buf and the selection to be gathered + * are specified by the dataspace src_space_id. The type of + * the data to be gathered is specified by type_id. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * 16 Jan 2013 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Dgather(hid_t src_space_id, void *src_buf, hid_t type_id, size_t dst_buf_size, + void *dst_buf, H5D_gather_func_t op, void *op_data) +{ + H5T_t *type; /* Datatype */ + H5S_t *src_space; /* Dataspace */ + H5S_sel_iter_t iter; /* Selection iteration info*/ + hbool_t iter_init = FALSE; /* Selection iteration info has been initialized */ + size_t type_size; /* Datatype element size */ + hssize_t nelmts; /* Number of remaining elements in selection */ + size_t dst_buf_nelmts; /* Number of elements that can fit in dst_buf */ + size_t nelmts_gathered; /* Number of elements gathered from src_buf */ + H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */ + H5D_dxpl_cache_t *dxpl_cache = &_dxpl_cache; /* Data transfer property cache */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE7("e", "i*xiz*xx*x", src_space_id, src_buf, type_id, dst_buf_size, + dst_buf, op, op_data); + + /* Check args */ + if(NULL == (src_space= (H5S_t *)H5I_object_verify(src_space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") + if(src_buf == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no source buffer provided") + if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") + if(dst_buf_size == 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "destination buffer size is 0") + if(dst_buf == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no destination buffer provided") + + /* Fill the DXPL cache values for later use */ + if(H5D__get_dxpl_cache(H5P_DATASET_XFER_DEFAULT, &dxpl_cache) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't fill dxpl cache") + + /* Get datatype element size */ + if(0 == (type_size = H5T_GET_SIZE(type))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get datatype size") + + /* Get number of elements in dst_buf_size */ + dst_buf_nelmts = dst_buf_size / type_size; + if(dst_buf_nelmts == 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "destination buffer is not large enough to hold one element") + + /* Get number of elements in dataspace */ + if((nelmts = (hssize_t)H5S_GET_SELECT_NPOINTS(src_space)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOUNT, FAIL, "unable to get number of elements in selection") + + /* If dst_buf is not large enough to hold all the elements, make sure there + * is a callback */ + if(((size_t)nelmts > dst_buf_nelmts) && (op == NULL)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no callback supplied and destination buffer too small") + + /* Initialize selection iterator */ + if(H5S_select_iter_init(&iter, src_space, type_size) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize selection iterator information") + iter_init = TRUE; + + /* Loop until all data has been scattered */ + while(nelmts > 0) { + /* Gather data */ + if(0 == (nelmts_gathered = H5D__gather_mem(src_buf, src_space, &iter, MIN(dst_buf_nelmts, (size_t)nelmts), dxpl_cache, dst_buf))) + HGOTO_ERROR(H5E_IO, H5E_CANTCOPY, FAIL, "gather failed") + HDassert(nelmts_gathered == MIN(dst_buf_nelmts, (size_t)nelmts)); + + /* Make callback to process dst_buf */ + if(op && op(dst_buf, nelmts_gathered * type_size, op_data) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CALLBACK, FAIL, "callback operator returned failure") + + nelmts -= (hssize_t)nelmts_gathered; + HDassert(op || (nelmts == 0)); + } /* end while */ + +done: + /* Release selection iterator */ + if(iter_init) { + if(H5S_SELECT_ITER_RELEASE(&iter) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't release selection iterator") + } /* end if */ + + FUNC_LEAVE_API(ret_value) +} /* H5Dgather() */ + diff --git a/src/H5FDcore.c b/src/H5FDcore.c index 9b4aadc..b51ea8c 100644 --- a/src/H5FDcore.c +++ b/src/H5FDcore.c @@ -17,57 +17,40 @@ * Programmer: Robb Matzke <matzke@llnl.gov> * Tuesday, August 10, 1999 * - * Purpose: A driver which stores the HDF5 data in main memory using - * only the HDF5 public API. This driver is useful for fast - * access to small, temporary hdf5 files. + * Purpose: A driver which stores the HDF5 data in main memory using + * only the HDF5 public API. This driver is useful for fast + * access to small, temporary hdf5 files. */ /* Interface initialization */ #define H5_INTERFACE_INIT_FUNC H5FD_core_init_interface -#include "H5private.h" /* Generic Functions */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5Fprivate.h" /* File access */ -#include "H5FDprivate.h" /* File drivers */ -#include "H5FDcore.h" /* Core file driver */ -#include "H5Iprivate.h" /* IDs */ -#include "H5MMprivate.h" /* Memory management */ -#include "H5Pprivate.h" /* Property lists */ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fprivate.h" /* File access */ +#include "H5FDprivate.h" /* File drivers */ +#include "H5FDcore.h" /* Core file driver */ +#include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Pprivate.h" /* Property lists */ /* The driver identification number, initialized at runtime */ static hid_t H5FD_CORE_g = 0; -/* Since Windows doesn't follow the rest of the world when it comes - * to POSIX I/O types, some typedefs and constants are needed to avoid - * making the code messy with #ifdefs. - * NOTE: These are only used when writing data to the backing store on - * file close. - */ -#ifdef H5_HAVE_WIN32_API -typedef unsigned int h5_core_io_t; -typedef int h5_core_io_ret_t; -static int H5_CORE_MAX_IO_BYTES_g = INT_MAX; -#else -/* Unix, everyone else */ -typedef size_t h5_core_io_t; -typedef ssize_t h5_core_io_ret_t; -static size_t H5_CORE_MAX_IO_BYTES_g = SSIZET_MAX; -#endif /* H5_HAVE_WIN32_API */ - -/* The description of a file belonging to this driver. The `eoa' and `eof' +/* The description of a file belonging to this driver. The 'eoa' and 'eof' * determine the amount of hdf5 address space in use and the high-water mark * of the file (the current size of the underlying memory). */ typedef struct H5FD_core_t { - H5FD_t pub; /*public stuff, must be first */ - char *name; /*for equivalence testing */ - unsigned char *mem; /*the underlying memory */ - haddr_t eoa; /*end of allocated region */ - haddr_t eof; /*current allocated size */ - size_t increment; /*multiples for mem allocation */ - hbool_t backing_store; /*write to file name on flush */ - int fd; /*backing store file descriptor */ + H5FD_t pub; /* public stuff, must be first */ + char *name; /* for equivalence testing */ + unsigned char *mem; /* the underlying memory */ + haddr_t eoa; /* end of allocated region */ + haddr_t eof; /* current allocated size */ + size_t increment; /* multiples for mem allocation */ + hbool_t backing_store; /* write to file name on flush */ + int fd; /* backing store file descriptor */ /* Information for determining uniqueness of a file with a backing store */ #ifndef H5_HAVE_WIN32_API /* On most systems the combination of device and i-node number uniquely @@ -100,8 +83,8 @@ typedef struct H5FD_core_t { HANDLE hFile; /* Native windows file handle */ #endif /* H5_HAVE_WIN32_API */ - hbool_t dirty; /*changes not saved? */ - H5FD_file_image_callbacks_t fi_callbacks; /* file image callbacks */ + hbool_t dirty; /* changes not saved? */ + H5FD_file_image_callbacks_t fi_callbacks; /* file image callbacks */ /* Information from file open flags, for SWMR access */ hbool_t swmr_read; /* Whether the file is open for SWMR read access */ @@ -109,38 +92,38 @@ typedef struct H5FD_core_t { /* Driver-specific file access properties */ typedef struct H5FD_core_fapl_t { - size_t increment; /*how much to grow memory */ - hbool_t backing_store; /*write to file name on flush */ + size_t increment; /* how much to grow memory */ + hbool_t backing_store; /* write to file name on flush */ } H5FD_core_fapl_t; /* Allocate memory in multiples of this size by default */ -#define H5FD_CORE_INCREMENT 8192 +#define H5FD_CORE_INCREMENT 8192 /* These macros check for overflow of various quantities. These macros * assume that file_offset_t is signed and haddr_t and size_t are unsigned. * - * ADDR_OVERFLOW: Checks whether a file address of type `haddr_t' - * is too large to be represented by the second argument - * of the file seek function. + * ADDR_OVERFLOW: Checks whether a file address of type `haddr_t' + * is too large to be represented by the second argument + * of the file seek function. * - * SIZE_OVERFLOW: Checks whether a buffer size of type `hsize_t' is too - * large to be represented by the `size_t' type. + * SIZE_OVERFLOW: Checks whether a buffer size of type `hsize_t' is too + * large to be represented by the `size_t' type. * - * REGION_OVERFLOW: Checks whether an address and size pair describe data - * which can be addressed entirely in memory. + * REGION_OVERFLOW: Checks whether an address and size pair describe data + * which can be addressed entirely in memory. */ -#define MAXADDR ((haddr_t)((~(size_t)0)-1)) -#define ADDR_OVERFLOW(A) (HADDR_UNDEF==(A) || (A) > (haddr_t)MAXADDR) -#define SIZE_OVERFLOW(Z) ((Z) > (hsize_t)MAXADDR) -#define REGION_OVERFLOW(A,Z) (ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) || \ - HADDR_UNDEF==(A)+(Z) || \ - (size_t)((A)+(Z))<(size_t)(A)) +#define MAXADDR ((haddr_t)((~(size_t)0)-1)) +#define ADDR_OVERFLOW(A) (HADDR_UNDEF==(A) || (A) > (haddr_t)MAXADDR) +#define SIZE_OVERFLOW(Z) ((Z) > (hsize_t)MAXADDR) +#define REGION_OVERFLOW(A,Z) (ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) || \ + HADDR_UNDEF==(A)+(Z) || \ + (size_t)((A)+(Z))<(size_t)(A)) /* Prototypes */ static herr_t H5FD_core_term(void); static void *H5FD_core_fapl_get(H5FD_t *_file); static H5FD_t *H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id, - haddr_t maxaddr); + haddr_t maxaddr); static herr_t H5FD_core_close(H5FD_t *_file); static int H5FD_core_cmp(const H5FD_t *_f1, const H5FD_t *_f2); static herr_t H5FD_core_query(const H5FD_t *_f1, unsigned long *flags); @@ -149,61 +132,58 @@ static herr_t H5FD_core_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr); static haddr_t H5FD_core_get_eof(const H5FD_t *_file); static herr_t H5FD_core_get_handle(H5FD_t *_file, hid_t fapl, void** file_handle); static herr_t H5FD_core_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, - size_t size, void *buf); + size_t size, void *buf); static herr_t H5FD_core_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, - size_t size, const void *buf); + size_t size, const void *buf); static herr_t H5FD_core_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing); static herr_t H5FD_core_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); static const H5FD_class_t H5FD_core_g = { - "core", /*name */ - MAXADDR, /*maxaddr */ - H5F_CLOSE_WEAK, /*fc_degree */ - H5FD_core_term, /*terminate */ - NULL, /*sb_size */ - NULL, /*sb_encode */ - NULL, /*sb_decode */ - sizeof(H5FD_core_fapl_t), /*fapl_size */ - H5FD_core_fapl_get, /*fapl_get */ - NULL, /*fapl_copy */ - NULL, /*fapl_free */ - 0, /*dxpl_size */ - NULL, /*dxpl_copy */ - NULL, /*dxpl_free */ - H5FD_core_open, /*open */ - H5FD_core_close, /*close */ - H5FD_core_cmp, /*cmp */ - H5FD_core_query, /*query */ - NULL, /*get_type_map */ - NULL, /*alloc */ - NULL, /*free */ - H5FD_core_get_eoa, /*get_eoa */ - H5FD_core_set_eoa, /*set_eoa */ - H5FD_core_get_eof, /*get_eof */ - H5FD_core_get_handle, /*get_handle */ - H5FD_core_read, /*read */ - H5FD_core_write, /*write */ - H5FD_core_flush, /*flush */ - H5FD_core_truncate, /*truncate */ - NULL, /*lock */ - NULL, /*unlock */ - H5FD_FLMAP_DICHOTOMY /*fl_map */ + "core", /* name */ + MAXADDR, /* maxaddr */ + H5F_CLOSE_WEAK, /* fc_degree */ + H5FD_core_term, /* terminate */ + NULL, /* sb_size */ + NULL, /* sb_encode */ + NULL, /* sb_decode */ + sizeof(H5FD_core_fapl_t), /* fapl_size */ + H5FD_core_fapl_get, /* fapl_get */ + NULL, /* fapl_copy */ + NULL, /* fapl_free */ + 0, /* dxpl_size */ + NULL, /* dxpl_copy */ + NULL, /* dxpl_free */ + H5FD_core_open, /* open */ + H5FD_core_close, /* close */ + H5FD_core_cmp, /* cmp */ + H5FD_core_query, /* query */ + NULL, /* get_type_map */ + NULL, /* alloc */ + NULL, /* free */ + H5FD_core_get_eoa, /* get_eoa */ + H5FD_core_set_eoa, /* set_eoa */ + H5FD_core_get_eof, /* get_eof */ + H5FD_core_get_handle, /* get_handle */ + H5FD_core_read, /* read */ + H5FD_core_write, /* write */ + H5FD_core_flush, /* flush */ + H5FD_core_truncate, /* truncate */ + NULL, /* lock */ + NULL, /* unlock */ + H5FD_FLMAP_DICHOTOMY /* fl_map */ }; -/*-------------------------------------------------------------------------- -NAME - H5FD_core_init_interface -- Initialize interface-specific information -USAGE - herr_t H5FD_core_init_interface() - -RETURNS - Non-negative on success/Negative on failure -DESCRIPTION - Initializes any interface-specific data or routines. (Just calls - H5FD_core_init currently). - ---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------- + * Function: H5FD_core_init_interface + * + * Purpose: Initializes any interface-specific data or routines. + * + * Return: Success: The driver ID for the core driver. + * Failure: Negative. + * + *------------------------------------------------------------------------- + */ static herr_t H5FD_core_init_interface(void) { @@ -214,16 +194,15 @@ H5FD_core_init_interface(void) /*------------------------------------------------------------------------- - * Function: H5FD_core_init + * Function: H5FD_core_init * - * Purpose: Initialize this driver by registering the driver with the - * library. + * Purpose: Initialize this driver by registering the driver with the + * library. * - * Return: Success: The driver ID for the core driver. + * Return: Success: The driver ID for the core driver. + * Failure: Negative. * - * Failure: Negative. - * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- @@ -231,15 +210,15 @@ H5FD_core_init_interface(void) hid_t H5FD_core_init(void) { - hid_t ret_value=H5FD_CORE_g; /* Return value */ + hid_t ret_value = H5FD_CORE_g; /* Return value */ FUNC_ENTER_NOAPI(FAIL) - if (H5I_VFL!=H5Iget_type(H5FD_CORE_g)) + if(H5I_VFL != H5Iget_type(H5FD_CORE_g)) H5FD_CORE_g = H5FD_register(&H5FD_core_g,sizeof(H5FD_class_t),FALSE); /* Set return value */ - ret_value=H5FD_CORE_g; + ret_value = H5FD_CORE_g; done: FUNC_LEAVE_NOAPI(ret_value) @@ -247,11 +226,11 @@ done: /*--------------------------------------------------------------------------- - * Function: H5FD_core_term + * Function: H5FD_core_term * - * Purpose: Shut down the VFD + * Purpose: Shut down the VFD * - * Returns: Non-negative on success or negative on failure + * Returns: SUCCEED (Can't fail) * * Programmer: Quincey Koziol * Friday, Jan 30, 2004 @@ -264,32 +243,32 @@ H5FD_core_term(void) FUNC_ENTER_NOAPI_NOINIT_NOERR /* Reset VFL ID */ - H5FD_CORE_g=0; + H5FD_CORE_g = 0; FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5FD_core_term() */ /*------------------------------------------------------------------------- - * Function: H5Pset_fapl_core + * Function: H5Pset_fapl_core * - * Purpose: Modify the file access property list to use the H5FD_CORE - * driver defined in this source file. The INCREMENT specifies - * how much to grow the memory each time we need more. + * Purpose: Modify the file access property list to use the H5FD_CORE + * driver defined in this source file. The INCREMENT specifies + * how much to grow the memory each time we need more. * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * - * Programmer: Robb Matzke - * Thursday, February 19, 1998 + * Programmer: Robb Matzke + * Thursday, February 19, 1998 * *------------------------------------------------------------------------- */ herr_t H5Pset_fapl_core(hid_t fapl_id, size_t increment, hbool_t backing_store) { - H5FD_core_fapl_t fa; - H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value; + H5FD_core_fapl_t fa; + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value; FUNC_ENTER_API(FAIL) H5TRACE3("e", "izb", fapl_id, increment, backing_store); @@ -309,26 +288,23 @@ done: /*------------------------------------------------------------------------- - * Function: H5Pget_fapl_core - * - * Purpose: Queries properties set by the H5Pset_fapl_core() function. + * Function: H5Pget_fapl_core * - * Return: Success: Non-negative + * Purpose: Queries properties set by the H5Pset_fapl_core() function. * - * Failure: Negative + * Return: SUCCEED/FAIL * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Tuesday, August 10, 1999 * *------------------------------------------------------------------------- */ herr_t -H5Pget_fapl_core(hid_t fapl_id, size_t *increment/*out*/, - hbool_t *backing_store/*out*/) +H5Pget_fapl_core(hid_t fapl_id, size_t *increment /*out*/, hbool_t *backing_store /*out*/) { - H5FD_core_fapl_t *fa; - H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value=SUCCEED; /* Return value */ + H5FD_core_fapl_t *fa; + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "ixx", fapl_id, increment, backing_store); @@ -351,15 +327,15 @@ done: /*------------------------------------------------------------------------- - * Function: H5FD_core_fapl_get + * Function: H5FD_core_fapl_get * - * Purpose: Returns a copy of the file access properties. + * Purpose: Returns a copy of the file access properties. * - * Return: Success: Ptr to new file access properties. + * Return: Success: Ptr to new file access properties. * - * Failure: NULL + * Failure: NULL * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Friday, August 13, 1999 * *------------------------------------------------------------------------- @@ -367,9 +343,9 @@ done: static void * H5FD_core_fapl_get(H5FD_t *_file) { - H5FD_core_t *file = (H5FD_core_t*)_file; - H5FD_core_fapl_t *fa; - void *ret_value; /* Return value */ + H5FD_core_t *file = (H5FD_core_t*)_file; + H5FD_core_fapl_t *fa; + void *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -380,7 +356,7 @@ H5FD_core_fapl_get(H5FD_t *_file) fa->backing_store = (hbool_t)(file->fd >= 0); /* Set return value */ - ret_value=fa; + ret_value = fa; done: FUNC_LEAVE_NOAPI(ret_value) @@ -388,36 +364,35 @@ done: /*------------------------------------------------------------------------- - * Function: H5FD_core_open + * Function: H5FD_core_open * - * Purpose: Create memory as an HDF5 file. + * Purpose: Create memory as an HDF5 file. * - * Return: Success: A pointer to a new file data structure. The - * public fields will be initialized by the - * caller, which is always H5FD_open(). + * Return: Success: A pointer to a new file data structure. The + * public fields will be initialized by the + * caller, which is always H5FD_open(). * - * Failure: NULL + * Failure: NULL * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- */ static H5FD_t * -H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id, - haddr_t maxaddr) +H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) { - int o_flags; - H5FD_core_t *file=NULL; - H5FD_core_fapl_t *fa=NULL; - H5P_genplist_t *plist; /* Property list pointer */ + int o_flags; + H5FD_core_t *file = NULL; + H5FD_core_fapl_t *fa = NULL; + H5P_genplist_t *plist; /* Property list pointer */ #ifdef H5_HAVE_WIN32_API struct _BY_HANDLE_FILE_INFORMATION fileinfo; #endif - h5_stat_t sb; - int fd=-1; - H5FD_file_image_info_t file_image_info; - H5FD_t *ret_value; + h5_stat_t sb; + int fd = -1; + H5FD_file_image_info_t file_image_info; + H5FD_t *ret_value; FUNC_ENTER_NOAPI_NOINIT @@ -557,20 +532,23 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id, /* Read in existing data, being careful of interrupted system calls, * partial results, and the end of the file. */ + + uint8_t *mem = file->mem; /* memory pointer for writes */ + while(size > 0) { - h5_core_io_t bytes_in = 0; /* # of bytes to read */ - h5_core_io_ret_t bytes_read = -1; /* # of bytes actually read */ + h5_posix_io_t bytes_in = 0; /* # of bytes to read */ + h5_posix_io_ret_t bytes_read = -1; /* # of bytes actually read */ /* Trying to read more bytes than the return type can handle is * undefined behavior in POSIX. */ - if(size > H5_CORE_MAX_IO_BYTES_g) - bytes_in = H5_CORE_MAX_IO_BYTES_g; + if(size > H5_POSIX_MAX_IO_BYTES) + bytes_in = H5_POSIX_MAX_IO_BYTES; else - bytes_in = (h5_core_io_t)size; + bytes_in = (h5_posix_io_t)size; do { - bytes_read = HDread(file->fd, file->mem, bytes_in); + bytes_read = HDread(file->fd, mem, bytes_in); } while(-1 == bytes_read && EINTR == errno); if(-1 == bytes_read) { /* error */ @@ -578,12 +556,13 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id, time_t mytime = HDtime(NULL); HDoff_t myoffset = HDlseek(file->fd, (HDoff_t)0, SEEK_CUR); - HGOTO_ERROR(H5E_IO, H5E_READERROR, NULL, "file read failed: time = %s, filename = '%s', file descriptor = %d, errno = %d, error message = '%s', file->mem = %p, size = %lu, offset = %llu", HDctime(&mytime), file->name, file->fd, myerrno, HDstrerror(myerrno), file->mem, (unsigned long)size, (unsigned long long)myoffset); + HGOTO_ERROR(H5E_IO, H5E_READERROR, NULL, "file read failed: time = %s, filename = '%s', file descriptor = %d, errno = %d, error message = '%s', file->mem = %p, total read size = %llu, bytes this sub-read = %llu, bytes actually read = %llu, offset = %llu", HDctime(&mytime), file->name, file->fd, myerrno, HDstrerror(myerrno), file->mem, (unsigned long long)size, (unsigned long long)bytes_in, (unsigned long long)bytes_read, (unsigned long long)myoffset); } /* end if */ HDassert(bytes_read >= 0); HDassert((size_t)bytes_read <= size); + mem += bytes_read; size -= (size_t)bytes_read; } /* end while */ } /* end else */ @@ -598,20 +577,26 @@ H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id, ret_value = (H5FD_t *)file; done: + if(!ret_value && file) { + if(file->fd >= 0) + HDclose(file->fd); + H5MM_xfree(file->name); + H5MM_xfree(file->mem); + H5MM_xfree(file); + } /* end if */ + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD_core_open() */ /*------------------------------------------------------------------------- - * Function: H5FD_core_close + * Function: H5FD_core_close * - * Purpose: Closes the file. + * Purpose: Closes the file. * - * Return: Success: 0 + * Return: SUCCEED/FAIL * - * Failure: -1 - * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- @@ -619,8 +604,8 @@ done: static herr_t H5FD_core_close(H5FD_t *_file) { - H5FD_core_t *file = (H5FD_core_t*)_file; - herr_t ret_value = SUCCEED; /* Return value */ + H5FD_core_t *file = (H5FD_core_t*)_file; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -651,19 +636,19 @@ done: /*------------------------------------------------------------------------- - * Function: H5FD_core_cmp + * Function: H5FD_core_cmp * - * Purpose: Compares two files belonging to this driver by name. If one - * file doesn't have a name then it is less than the other file. - * If neither file has a name then the comparison is by file - * address. + * Purpose: Compares two files belonging to this driver by name. If one + * file doesn't have a name then it is less than the other file. + * If neither file has a name then the comparison is by file + * address. * - * Return: Success: A value like strcmp() + * Return: Success: A value like strcmp() * - * Failure: never fails (arguments were checked by the - * caller). + * Failure: never fails (arguments were checked by the + * caller). * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- @@ -671,9 +656,9 @@ done: static int H5FD_core_cmp(const H5FD_t *_f1, const H5FD_t *_f2) { - const H5FD_core_t *f1 = (const H5FD_core_t*)_f1; - const H5FD_core_t *f2 = (const H5FD_core_t*)_f2; - int ret_value = 0; + const H5FD_core_t *f1 = (const H5FD_core_t*)_f1; + const H5FD_core_t *f2 = (const H5FD_core_t*)_f2; + int ret_value = 0; FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -735,15 +720,14 @@ done: /*------------------------------------------------------------------------- - * Function: H5FD_core_query + * Function: H5FD_core_query * - * Purpose: Set the flags that this VFL driver is capable of supporting. + * Purpose: Set the flags that this VFL driver is capable of supporting. * (listed in H5FDpublic.h) * - * Return: Success: non-negative - * Failure: negative + * Return: SUCCEED (Can't fail) * - * Programmer: Quincey Koziol + * Programmer: Quincey Koziol * Tuesday, October 7, 2008 * *------------------------------------------------------------------------- @@ -751,7 +735,7 @@ done: static herr_t H5FD_core_query(const H5FD_t * _file, unsigned long *flags /* out */) { - const H5FD_core_t *file = (const H5FD_core_t*)_file; + const H5FD_core_t *file = (const H5FD_core_t*)_file; FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -775,17 +759,15 @@ H5FD_core_query(const H5FD_t * _file, unsigned long *flags /* out */) /*------------------------------------------------------------------------- - * Function: H5FD_core_get_eoa - * - * Purpose: Gets the end-of-address marker for the file. The EOA marker - * is the first address past the last byte allocated in the - * format address space. + * Function: H5FD_core_get_eoa * - * Return: Success: The end-of-address marker. + * Purpose: Gets the end-of-address marker for the file. The EOA marker + * is the first address past the last byte allocated in the + * format address space. * - * Failure: HADDR_UNDEF + * Return: The end-of-address marker. (Can't fail) * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Monday, August 2, 1999 * *------------------------------------------------------------------------- @@ -793,7 +775,7 @@ H5FD_core_query(const H5FD_t * _file, unsigned long *flags /* out */) static haddr_t H5FD_core_get_eoa(const H5FD_t *_file, H5FD_mem_t UNUSED type) { - const H5FD_core_t *file = (const H5FD_core_t*)_file; + const H5FD_core_t *file = (const H5FD_core_t*)_file; FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -802,17 +784,15 @@ H5FD_core_get_eoa(const H5FD_t *_file, H5FD_mem_t UNUSED type) /*------------------------------------------------------------------------- - * Function: H5FD_core_set_eoa + * Function: H5FD_core_set_eoa * - * Purpose: Set the end-of-address marker for the file. This function is - * called shortly after an existing HDF5 file is opened in order - * to tell the driver where the end of the HDF5 data is located. + * Purpose: Set the end-of-address marker for the file. This function is + * called shortly after an existing HDF5 file is opened in order + * to tell the driver where the end of the HDF5 data is located. * - * Return: Success: 0 + * Return: SUCCEED/FAIL * - * Failure: -1 - * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- @@ -820,8 +800,8 @@ H5FD_core_get_eoa(const H5FD_t *_file, H5FD_mem_t UNUSED type) static herr_t H5FD_core_set_eoa(H5FD_t *_file, H5FD_mem_t UNUSED type, haddr_t addr) { - H5FD_core_t *file = (H5FD_core_t*)_file; - herr_t ret_value = SUCCEED; /* Return value */ + H5FD_core_t *file = (H5FD_core_t*)_file; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -836,19 +816,17 @@ done: /*------------------------------------------------------------------------- - * Function: H5FD_core_get_eof - * - * Purpose: Returns the end-of-file marker, which is the greater of - * either the size of the underlying memory or the HDF5 - * end-of-address markers. + * Function: H5FD_core_get_eof * - * Return: Success: End of file address, the first address past - * the end of the "file", either the memory - * or the HDF5 file. + * Purpose: Returns the end-of-file marker, which is the greater of + * either the size of the underlying memory or the HDF5 + * end-of-address markers. * - * Failure: HADDR_UNDEF + * Return: End of file address, the first address past + * the end of the "file", either the memory + * or the HDF5 file. (Can't fail) * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- @@ -856,7 +834,7 @@ done: static haddr_t H5FD_core_get_eof(const H5FD_t *_file) { - const H5FD_core_t *file = (const H5FD_core_t*)_file; + const H5FD_core_t *file = (const H5FD_core_t*)_file; FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -867,9 +845,9 @@ H5FD_core_get_eof(const H5FD_t *_file) /*------------------------------------------------------------------------- * Function: H5FD_core_get_handle * - * Purpose: Returns the file handle of CORE file driver. + * Purpose: Gets the file handle of CORE file driver. * - * Returns: Non-negative if succeed or negative if fails. + * Returns: SUCCEED/FAIL * * Programmer: Raymond Lu * Sept. 16, 2002 @@ -880,7 +858,7 @@ static herr_t H5FD_core_get_handle(H5FD_t *_file, hid_t fapl, void** file_handle) { H5FD_core_t *file = (H5FD_core_t *)_file; /* core VFD info */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -925,26 +903,25 @@ done: /*------------------------------------------------------------------------- - * Function: H5FD_core_read + * Function: H5FD_core_read * - * Purpose: Reads SIZE bytes of data from FILE beginning at address ADDR - * into buffer BUF according to data transfer properties in - * DXPL_ID. + * Purpose: Reads SIZE bytes of data from FILE beginning at address ADDR + * into buffer BUF according to data transfer properties in + * DXPL_ID. * - * Return: Success: Zero. Result is stored in caller-supplied - * buffer BUF. + * Return: Success: SUCCEED. Result is stored in caller-supplied + * buffer BUF. * - * Failure: -1, Contents of buffer BUF are undefined. + * Failure: FAIL, Contents of buffer BUF are undefined. * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- */ -/* ARGSUSED */ static herr_t H5FD_core_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr, - size_t size, void *buf/*out*/) + size_t size, void *buf/*out*/) { H5FD_core_t *file = (H5FD_core_t*)_file; herr_t ret_value=SUCCEED; /* Return value */ @@ -997,28 +974,25 @@ done: /*------------------------------------------------------------------------- - * Function: H5FD_core_write - * - * Purpose: Writes SIZE bytes of data to FILE beginning at address ADDR - * from buffer BUF according to data transfer properties in - * DXPL_ID. + * Function: H5FD_core_write * - * Return: Success: Zero + * Purpose: Writes SIZE bytes of data to FILE beginning at address ADDR + * from buffer BUF according to data transfer properties in + * DXPL_ID. * - * Failure: -1 + * Return: SUCCEED/FAIL * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- */ -/* ARGSUSED */ static herr_t H5FD_core_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr, - size_t size, const void *buf) + size_t size, const void *buf) { H5FD_core_t *file = (H5FD_core_t*)_file; - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -1057,7 +1031,7 @@ H5FD_core_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, had } /* end else */ #ifdef H5_CLEAR_MEMORY -HDmemset(x + file->eof, 0, (size_t)(new_eof - file->eof)); + HDmemset(x + file->eof, 0, (size_t)(new_eof - file->eof)); #endif /* H5_CLEAR_MEMORY */ file->mem = x; @@ -1076,49 +1050,46 @@ done: /*------------------------------------------------------------------------- - * Function: H5FD_core_flush + * Function: H5FD_core_flush * - * Purpose: Flushes the file to backing store if there is any and if the - * dirty flag is set. + * Purpose: Flushes the file to backing store if there is any and if the + * dirty flag is set. * - * Return: Success: 0 + * Return: SUCCEED/FAIL * - * Failure: -1 - * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Friday, October 15, 1999 * *------------------------------------------------------------------------- */ -/* ARGSUSED */ static herr_t H5FD_core_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned UNUSED closing) { - H5FD_core_t *file = (H5FD_core_t*)_file; - herr_t ret_value=SUCCEED; /* Return value */ + H5FD_core_t *file = (H5FD_core_t*)_file; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* Write to backing store */ - if (file->dirty && file->fd>=0 && file->backing_store) { + if (file->dirty && file->fd >= 0 && file->backing_store) { haddr_t size = file->eof; unsigned char *ptr = file->mem; - if (0!=HDlseek(file->fd, (off_t)0, SEEK_SET)) + if(0 != HDlseek(file->fd, (off_t)0, SEEK_SET)) HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "error seeking in backing store") while (size > 0) { - h5_core_io_t bytes_in = 0; /* # of bytes to write */ - h5_core_io_ret_t bytes_wrote = -1; /* # of bytes written */ + h5_posix_io_t bytes_in = 0; /* # of bytes to write */ + h5_posix_io_ret_t bytes_wrote = -1; /* # of bytes written */ /* Trying to write more bytes than the return type can handle is * undefined behavior in POSIX. */ - if(size > H5_CORE_MAX_IO_BYTES_g) - bytes_in = H5_CORE_MAX_IO_BYTES_g; + if(size > H5_POSIX_MAX_IO_BYTES) + bytes_in = H5_POSIX_MAX_IO_BYTES; else - bytes_in = (h5_core_io_t)size; + bytes_in = (h5_posix_io_t)size; do { bytes_wrote = HDwrite(file->fd, ptr, bytes_in); @@ -1129,7 +1100,7 @@ H5FD_core_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned UNUSED closing) time_t mytime = HDtime(NULL); HDoff_t myoffset = HDlseek(file->fd, (HDoff_t)0, SEEK_CUR); - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "write to backing store failed: time = %s, filename = '%s', file descriptor = %d, errno = %d, error message = '%s', ptr = %p, size = %lu, offset = %llu", HDctime(&mytime), file->name, file->fd, myerrno, HDstrerror(myerrno), ptr, (unsigned long)size, (unsigned long long)myoffset); + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "write to backing store failed: time = %s, filename = '%s', file descriptor = %d, errno = %d, error message = '%s', ptr = %p, total write size = %llu, bytes this sub-write = %llu, bytes actually written = %llu, offset = %llu", HDctime(&mytime), file->name, file->fd, myerrno, HDstrerror(myerrno), ptr, (unsigned long long)size, (unsigned long long)bytes_in, (unsigned long long)bytes_wrote, (unsigned long long)myoffset); } /* end if */ HDassert(bytes_wrote > 0); @@ -1149,42 +1120,40 @@ done: /*------------------------------------------------------------------------- - * Function: H5FD_core_truncate + * Function: H5FD_core_truncate * - * Purpose: Makes sure that the true file size is the same (or larger) - * than the end-of-address. + * Purpose: Makes sure that the true file size is the same (or larger) + * than the end-of-address. * - * Addendum -- 12/2/11 - * For file images opened with the core file driver, it is - * necessary that we avoid reallocating the core file driver's - * buffer uneccessarily. + * Addendum -- 12/2/11 + * For file images opened with the core file driver, it is + * necessary that we avoid reallocating the core file driver's + * buffer uneccessarily. * - * To this end, I have made the following functional changes - * to this function. + * To this end, I have made the following functional changes + * to this function. * - * If we are closing, and there is no backing store, this - * function becomes a no-op. + * If we are closing, and there is no backing store, this + * function becomes a no-op. * - * If we are closing, and there is backing store, we set the - * eof to equal the eoa, and truncate the backing store to - * the new eof + * If we are closing, and there is backing store, we set the + * eof to equal the eoa, and truncate the backing store to + * the new eof * - * If we are not closing, we realloc the buffer to size equal - * to the smallest multiple of the allocation increment that - * equals or exceeds the eoa and set the eof accordingly. - * Note that we no longer truncate the backing store to the - * new eof if applicable. - * -- JRM + * If we are not closing, we realloc the buffer to size equal + * to the smallest multiple of the allocation increment that + * equals or exceeds the eoa and set the eof accordingly. + * Note that we no longer truncate the backing store to the + * new eof if applicable. + * -- JRM * - * Return: Success: Non-negative - * Failure: Negative + * Return: SUCCEED/FAIL * - * Programmer: Quincey Koziol + * Programmer: Quincey Koziol * Tuesday, October 7, 2008 * *------------------------------------------------------------------------- */ -/* ARGSUSED */ static herr_t H5FD_core_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t closing) { @@ -1275,4 +1244,3 @@ H5FD_core_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t closing) done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD_core_truncate() */ - diff --git a/src/H5FDlog.c b/src/H5FDlog.c index 89a0a28..ac55427 100644 --- a/src/H5FDlog.c +++ b/src/H5FDlog.c @@ -14,50 +14,35 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* - * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu> + * Programmer: Quincey Koziol <koziol@hdfgroup.org> * Monday, April 17, 2000 * - * Purpose: The POSIX unbuffered file driver using only the HDF5 public - * API and with a few optimizations: the lseek() call is made - * only when the current file position is unknown or needs to be - * changed based on previous I/O through this driver (don't mix - * I/O from this driver with I/O from other parts of the - * application to the same file). - * With custom modifications... + * Purpose: The POSIX unbuffered file driver using only the HDF5 public + * API and with a few optimizations: the lseek() call is made + * only when the current file position is unknown or needs to be + * changed based on previous I/O through this driver (don't mix + * I/O from this driver with I/O from other parts of the + * application to the same file). + * With custom modifications... */ /* Interface initialization */ #define H5_INTERFACE_INIT_FUNC H5FD_log_init_interface -#include "H5private.h" /* Generic Functions */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5Fprivate.h" /* File access */ -#include "H5FDprivate.h" /* File drivers */ -#include "H5FDlog.h" /* Logging file driver */ -#include "H5FLprivate.h" /* Free Lists */ -#include "H5Iprivate.h" /* IDs */ -#include "H5MMprivate.h" /* Memory management */ -#include "H5Pprivate.h" /* Property lists */ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fprivate.h" /* File access */ +#include "H5FDprivate.h" /* File drivers */ +#include "H5FDlog.h" /* Logging file driver */ +#include "H5FLprivate.h" /* Free Lists */ +#include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Pprivate.h" /* Property lists */ /* The driver identification number, initialized at runtime */ static hid_t H5FD_LOG_g = 0; -/* Since Windows doesn't follow the rest of the world when it comes - * to POSIX I/O types, some typedefs and constants are needed to avoid - * making the code messy with #ifdefs. - */ -#ifdef H5_HAVE_WIN32_API -typedef unsigned int h5_log_io_t; -typedef int h5_log_io_ret_t; -static int H5_LOG_MAX_IO_BYTES_g = INT_MAX; -#else -/* Unix, everyone else */ -typedef size_t h5_log_io_t; -typedef ssize_t h5_log_io_ret_t; -static size_t H5_LOG_MAX_IO_BYTES_g = SSIZET_MAX; -#endif /* H5_HAVE_WIN32_API */ - /* Driver-specific file access properties */ typedef struct H5FD_log_fapl_t { char *logfile; /* Allocated log file name */ @@ -167,24 +152,23 @@ typedef struct H5FD_log_t { * These macros check for overflow of various quantities. These macros * assume that HDoff_t is signed and haddr_t and size_t are unsigned. * - * ADDR_OVERFLOW: Checks whether a file address of type `haddr_t' - * is too large to be represented by the second argument - * of the file seek function. + * ADDR_OVERFLOW: Checks whether a file address of type `haddr_t' + * is too large to be represented by the second argument + * of the file seek function. * - * SIZE_OVERFLOW: Checks whether a buffer size of type `hsize_t' is too - * large to be represented by the `size_t' type. + * SIZE_OVERFLOW: Checks whether a buffer size of type `hsize_t' is too + * large to be represented by the `size_t' type. * - * REGION_OVERFLOW: Checks whether an address and size pair describe data - * which can be addressed entirely by the second - * argument of the file seek function. + * REGION_OVERFLOW: Checks whether an address and size pair describe data + * which can be addressed entirely by the second + * argument of the file seek function. */ -#define MAXADDR (((haddr_t)1<<(8*sizeof(HDoff_t)-1))-1) -#define ADDR_OVERFLOW(A) (HADDR_UNDEF==(A) || \ - ((A) & ~(haddr_t)MAXADDR)) -#define SIZE_OVERFLOW(Z) ((Z) & ~(hsize_t)MAXADDR) -#define REGION_OVERFLOW(A,Z) (ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) || \ - HADDR_UNDEF==(A)+(Z) || \ - (HDoff_t)((A)+(Z))<(HDoff_t)(A)) +#define MAXADDR (((haddr_t)1<<(8*sizeof(HDoff_t)-1))-1) +#define ADDR_OVERFLOW(A) (HADDR_UNDEF==(A) || ((A) & ~(haddr_t)MAXADDR)) +#define SIZE_OVERFLOW(Z) ((Z) & ~(hsize_t)MAXADDR) +#define REGION_OVERFLOW(A,Z) (ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) || \ + HADDR_UNDEF==(A)+(Z) || \ + (HDoff_t)((A)+(Z))<(HDoff_t)(A)) /* Prototypes */ static herr_t H5FD_log_term(void); @@ -192,7 +176,7 @@ static void *H5FD_log_fapl_get(H5FD_t *file); static void *H5FD_log_fapl_copy(const void *_old_fa); static herr_t H5FD_log_fapl_free(void *_fa); static H5FD_t *H5FD_log_open(const char *name, unsigned flags, hid_t fapl_id, - haddr_t maxaddr); + haddr_t maxaddr); static herr_t H5FD_log_close(H5FD_t *_file); static int H5FD_log_cmp(const H5FD_t *_f1, const H5FD_t *_f2); static herr_t H5FD_log_query(const H5FD_t *_f1, unsigned long *flags); @@ -202,9 +186,9 @@ static herr_t H5FD_log_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr); static haddr_t H5FD_log_get_eof(const H5FD_t *_file); static herr_t H5FD_log_get_handle(H5FD_t *_file, hid_t fapl, void** file_handle); static herr_t H5FD_log_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, - size_t size, void *buf); + size_t size, void *buf); static herr_t H5FD_log_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, - size_t size, const void *buf); + size_t size, const void *buf); static herr_t H5FD_log_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); static const H5FD_class_t H5FD_log_g = { @@ -246,19 +230,16 @@ static const H5FD_class_t H5FD_log_g = { H5FL_DEFINE_STATIC(H5FD_log_t); -/*-------------------------------------------------------------------------- -NAME - H5FD_log_init_interface -- Initialize interface-specific information -USAGE - herr_t H5FD_log_init_interface() - -RETURNS - Non-negative on success/Negative on failure -DESCRIPTION - Initializes any interface-specific data or routines. (Just calls - H5FD_log_init currently). - ---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------- + * Function: H5FD_log_init_interface + * + * Purpose: Initializes any interface-specific data or routines. + * + * Return: Success: The driver ID for the log driver. + * Failure: Negative. + * + *------------------------------------------------------------------------- + */ static herr_t H5FD_log_init_interface(void) { @@ -269,15 +250,15 @@ H5FD_log_init_interface(void) /*------------------------------------------------------------------------- - * Function: H5FD_log_init + * Function: H5FD_log_init * - * Purpose: Initialize this driver by registering the driver with the - * library. + * Purpose: Initialize this driver by registering the driver with the + * library. * - * Return: Success: The driver ID for the log driver. - * Failure: Negative. + * Return: Success: The driver ID for the log driver. + * Failure: Negative. * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- @@ -301,11 +282,11 @@ done: /*--------------------------------------------------------------------------- - * Function: H5FD_log_term + * Function: H5FD_log_term * - * Purpose: Shut down the VFD + * Purpose: Shut down the VFD * - * Returns: Non-negative on success or negative on failure + * Returns: SUCCEED (Can't fail) * * Programmer: Quincey Koziol * Friday, Jan 30, 2004 @@ -325,15 +306,15 @@ H5FD_log_term(void) /*------------------------------------------------------------------------- - * Function: H5Pset_fapl_log + * Function: H5Pset_fapl_log * - * Purpose: Modify the file access property list to use the H5FD_LOG - * driver defined in this source file. + * Purpose: Modify the file access property list to use the H5FD_LOG + * driver defined in this source file. * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * - * Programmer: Robb Matzke - * Thursday, February 19, 1998 + * Programmer: Robb Matzke + * Thursday, February 19, 1998 * *------------------------------------------------------------------------- */ @@ -366,17 +347,17 @@ done: /*------------------------------------------------------------------------- - * Function: H5FD_log_fapl_get + * Function: H5FD_log_fapl_get * - * Purpose: Returns a file access property list which indicates how the - * specified file is being accessed. The return list could be - * used to access another file the same way. + * Purpose: Returns a file access property list which indicates how the + * specified file is being accessed. The return list could be + * used to access another file the same way. * - * Return: Success: Ptr to new file access property list with all - * members copied from the file struct. - * Failure: NULL + * Return: Success: Ptr to new file access property list with all + * members copied from the file struct. + * Failure: NULL * - * Programmer: Quincey Koziol + * Programmer: Quincey Koziol * Thursday, April 20, 2000 * *------------------------------------------------------------------------- @@ -384,8 +365,8 @@ done: static void * H5FD_log_fapl_get(H5FD_t *_file) { - H5FD_log_t *file = (H5FD_log_t *)_file; - void *ret_value; /* Return value */ + H5FD_log_t *file = (H5FD_log_t *)_file; + void *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -397,14 +378,14 @@ H5FD_log_fapl_get(H5FD_t *_file) /*------------------------------------------------------------------------- - * Function: H5FD_log_fapl_copy + * Function: H5FD_log_fapl_copy * - * Purpose: Copies the log-specific file access properties. + * Purpose: Copies the log-specific file access properties. * - * Return: Success: Ptr to a new property list - * Failure: NULL + * Return: Success: Ptr to a new property list + * Failure: NULL * - * Programmer: Quincey Koziol + * Programmer: Quincey Koziol * Thursday, April 20, 2000 * *------------------------------------------------------------------------- @@ -412,9 +393,9 @@ H5FD_log_fapl_get(H5FD_t *_file) static void * H5FD_log_fapl_copy(const void *_old_fa) { - const H5FD_log_fapl_t *old_fa = (const H5FD_log_fapl_t*)_old_fa; - H5FD_log_fapl_t *new_fa = NULL; /* New FAPL info */ - void *ret_value; /* Return value */ + const H5FD_log_fapl_t *old_fa = (const H5FD_log_fapl_t*)_old_fa; + H5FD_log_fapl_t *new_fa = NULL; /* New FAPL info */ + void *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -448,14 +429,13 @@ done: /*------------------------------------------------------------------------- - * Function: H5FD_log_fapl_free + * Function: H5FD_log_fapl_free * - * Purpose: Frees the log-specific file access properties. + * Purpose: Frees the log-specific file access properties. * - * Return: Success: 0 - * Failure: -1 + * Return: SUCCEED (Can't fail) * - * Programmer: Quincey Koziol + * Programmer: Quincey Koziol * Thursday, April 20, 2000 * *------------------------------------------------------------------------- @@ -477,16 +457,16 @@ H5FD_log_fapl_free(void *_fa) /*------------------------------------------------------------------------- - * Function: H5FD_log_open + * Function: H5FD_log_open * - * Purpose: Create and/or opens a file as an HDF5 file. + * Purpose: Create and/or opens a file as an HDF5 file. * - * Return: Success: A pointer to a new file data structure. The - * public fields will be initialized by the - * caller, which is always H5FD_open(). - * Failure: NULL + * Return: Success: A pointer to a new file data structure. The + * public fields will be initialized by the + * caller, which is always H5FD_open(). + * Failure: NULL * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- @@ -494,11 +474,11 @@ H5FD_log_fapl_free(void *_fa) static H5FD_t * H5FD_log_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) { - H5FD_log_t *file = NULL; - H5P_genplist_t *plist; /* Property list */ - H5FD_log_fapl_t *fa; /* File access property list information */ - int fd = (-1); /* File descriptor */ - int o_flags; /* Flags for open() call */ + H5FD_log_t *file = NULL; + H5P_genplist_t *plist; /* Property list */ + H5FD_log_fapl_t *fa; /* File access property list information */ + int fd = -1; /* File descriptor */ + int o_flags; /* Flags for open() call */ #ifdef H5_HAVE_WIN32_API struct _BY_HANDLE_FILE_INFORMATION fileinfo; #endif @@ -507,8 +487,8 @@ H5FD_log_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) struct timeval open_timeval_diff; struct timeval stat_timeval_diff; #endif /* H5_HAVE_GETTIMEOFDAY */ - h5_stat_t sb; - H5FD_t *ret_value; /* Return value */ + h5_stat_t sb; + H5FD_t *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -689,14 +669,14 @@ done: /*------------------------------------------------------------------------- - * Function: H5FD_log_close + * Function: H5FD_log_close * - * Purpose: Closes an HDF5 file. + * Purpose: Closes an HDF5 file. * - * Return: Success: 0 - * Failure: -1, file not closed. + * Return: Success: SUCCEED + * Failure: FAIL, file not closed. * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- @@ -837,16 +817,16 @@ done: /*------------------------------------------------------------------------- - * Function: H5FD_log_cmp + * Function: H5FD_log_cmp * - * Purpose: Compares two files belonging to this driver using an - * arbitrary (but consistent) ordering. + * Purpose: Compares two files belonging to this driver using an + * arbitrary (but consistent) ordering. * - * Return: Success: A value like strcmp() - * Failure: never fails (arguments were checked by the - * caller). + * Return: Success: A value like strcmp() + * Failure: never fails (arguments were checked by the + * caller). * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- @@ -854,8 +834,8 @@ done: static int H5FD_log_cmp(const H5FD_t *_f1, const H5FD_t *_f2) { - const H5FD_log_t *f1 = (const H5FD_log_t *)_f1; - const H5FD_log_t *f2 = (const H5FD_log_t *)_f2; + const H5FD_log_t *f1 = (const H5FD_log_t *)_f1; + const H5FD_log_t *f2 = (const H5FD_log_t *)_f2; int ret_value = 0; FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -898,15 +878,14 @@ done: /*------------------------------------------------------------------------- - * Function: H5FD_log_query + * Function: H5FD_log_query * - * Purpose: Set the flags that this VFL driver is capable of supporting. + * Purpose: Set the flags that this VFL driver is capable of supporting. * (listed in H5FDpublic.h) * - * Return: Success: non-negative - * Failure: negative + * Return: SUCCEED (Can't fail) * - * Programmer: Quincey Koziol + * Programmer: Quincey Koziol * Friday, August 25, 2000 * *------------------------------------------------------------------------- @@ -914,7 +893,7 @@ done: static herr_t H5FD_log_query(const H5FD_t *_file, unsigned long *flags /* out */) { - const H5FD_log_t *file = (const H5FD_log_t *)_file; + const H5FD_log_t *file = (const H5FD_log_t *)_file; FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -937,19 +916,18 @@ H5FD_log_query(const H5FD_t *_file, unsigned long *flags /* out */) /*------------------------------------------------------------------------- - * Function: H5FD_log_alloc + * Function: H5FD_log_alloc * - * Purpose: Allocate file memory. + * Purpose: Allocate file memory. * - * Return: Success: Address of new memory - * Failure: HADDR_UNDEF + * Return: Success: Address of new memory + * Failure: HADDR_UNDEF * - * Programmer: Quincey Koziol + * Programmer: Quincey Koziol * Monday, April 17, 2000 * *------------------------------------------------------------------------- */ -/* ARGSUSED */ static haddr_t H5FD_log_alloc(H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id, hsize_t size) { @@ -991,16 +969,16 @@ H5FD_log_alloc(H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id, hsize_t siz /*------------------------------------------------------------------------- - * Function: H5FD_log_get_eoa + * Function: H5FD_log_get_eoa * - * Purpose: Gets the end-of-address marker for the file. The EOA marker - * is the first address past the last byte allocated in the - * format address space. + * Purpose: Gets the end-of-address marker for the file. The EOA marker + * is the first address past the last byte allocated in the + * format address space. * - * Return: Success: The end-of-address marker. - * Failure: HADDR_UNDEF + * Return: Success: The end-of-address marker. + * Failure: HADDR_UNDEF * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Monday, August 2, 1999 * *------------------------------------------------------------------------- @@ -1008,7 +986,7 @@ H5FD_log_alloc(H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id, hsize_t siz static haddr_t H5FD_log_get_eoa(const H5FD_t *_file, H5FD_mem_t UNUSED type) { - const H5FD_log_t *file = (const H5FD_log_t *)_file; + const H5FD_log_t *file = (const H5FD_log_t *)_file; FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -1017,16 +995,15 @@ H5FD_log_get_eoa(const H5FD_t *_file, H5FD_mem_t UNUSED type) /*------------------------------------------------------------------------- - * Function: H5FD_log_set_eoa + * Function: H5FD_log_set_eoa * - * Purpose: Set the end-of-address marker for the file. This function is - * called shortly after an existing HDF5 file is opened in order - * to tell the driver where the end of the HDF5 data is located. + * Purpose: Set the end-of-address marker for the file. This function is + * called shortly after an existing HDF5 file is opened in order + * to tell the driver where the end of the HDF5 data is located. * - * Return: Success: 0 - * Failure: -1 + * Return: SUCCEED (Can't fail) * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- @@ -1034,25 +1011,25 @@ H5FD_log_get_eoa(const H5FD_t *_file, H5FD_mem_t UNUSED type) static herr_t H5FD_log_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr) { - H5FD_log_t *file = (H5FD_log_t *)_file; + H5FD_log_t *file = (H5FD_log_t *)_file; FUNC_ENTER_NOAPI_NOINIT_NOERR if(file->fa.flags != 0) { - if(H5F_addr_gt(addr, file->eoa) && H5F_addr_gt(addr, 0)) { - hsize_t size = addr - file->eoa; + if(H5F_addr_gt(addr, file->eoa) && H5F_addr_gt(addr, 0)) { + hsize_t size = addr - file->eoa; /* Retain the flavor of the space allocated by the extension */ - if(file->fa.flags & H5FD_LOG_FLAVOR) { - HDassert(addr < file->iosize); - H5_CHECK_OVERFLOW(size, hsize_t, size_t); - HDmemset(&file->flavor[file->eoa], (int)type, (size_t)size); - } /* end if */ + if(file->fa.flags & H5FD_LOG_FLAVOR) { + HDassert(addr < file->iosize); + H5_CHECK_OVERFLOW(size, hsize_t, size_t); + HDmemset(&file->flavor[file->eoa], (int)type, (size_t)size); + } /* end if */ /* Log the extension like an allocation */ - if(file->fa.flags & H5FD_LOG_ALLOC) - HDfprintf(file->logfp, "%10a-%10a (%10Hu bytes) (%s) Allocated\n", file->eoa, addr, size, flavors[type]); - } /* end if */ + if(file->fa.flags & H5FD_LOG_ALLOC) + HDfprintf(file->logfp, "%10a-%10a (%10Hu bytes) (%s) Allocated\n", file->eoa, addr, size, flavors[type]); + } /* end if */ } /* end if */ file->eoa = addr; @@ -1062,18 +1039,18 @@ H5FD_log_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr) /*------------------------------------------------------------------------- - * Function: H5FD_log_get_eof + * Function: H5FD_log_get_eof * - * Purpose: Returns the end-of-file marker, which is the greater of - * either the filesystem end-of-file or the HDF5 end-of-address - * markers. + * Purpose: Returns the end-of-file marker, which is the greater of + * either the filesystem end-of-file or the HDF5 end-of-address + * markers. * - * Return: Success: End of file address, the first address past - * the end of the "file", either the filesystem file - * or the HDF5 file. - * Failure: HADDR_UNDEF + * Return: Success: End of file address, the first address past + * the end of the "file", either the filesystem file + * or the HDF5 file. + * Failure: HADDR_UNDEF * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- @@ -1094,14 +1071,13 @@ H5FD_log_get_eof(const H5FD_t *_file) * * Purpose: Returns the file handle of LOG file driver. * - * Returns: Non-negative if succeed or negative if fails. + * Returns: SUCCEED/FAIL * * Programmer: Raymond Lu * Sept. 16, 2002 * *------------------------------------------------------------------------- */ -/* ARGSUSED */ static herr_t H5FD_log_get_handle(H5FD_t *_file, hid_t UNUSED fapl, void **file_handle) { @@ -1121,27 +1097,26 @@ done: /*------------------------------------------------------------------------- - * Function: H5FD_log_read + * Function: H5FD_log_read * - * Purpose: Reads SIZE bytes of data from FILE beginning at address ADDR - * into buffer BUF according to data transfer properties in - * DXPL_ID. + * Purpose: Reads SIZE bytes of data from FILE beginning at address ADDR + * into buffer BUF according to data transfer properties in + * DXPL_ID. * - * Return: Success: Zero. Result is stored in caller-supplied - * buffer BUF. - * Failure: -1, Contents of buffer BUF are undefined. + * Return: Success: SUCCEED. Result is stored in caller-supplied + * buffer BUF. + * Failure: FAIL, Contents of buffer BUF are undefined. * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- */ -/* ARGSUSED */ static herr_t H5FD_log_read(H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id, haddr_t addr, - size_t size, void *buf/*out*/) + size_t size, void *buf/*out*/) { - H5FD_log_t *file = (H5FD_log_t *)_file; + H5FD_log_t *file = (H5FD_log_t *)_file; size_t orig_size = size; /* Save the original size for later */ haddr_t orig_addr = addr; #ifdef H5_HAVE_GETTIMEOFDAY @@ -1235,16 +1210,16 @@ H5FD_log_read(H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id, haddr_t addr #endif /* H5_HAVE_GETTIMEOFDAY */ while(size > 0) { - h5_log_io_t bytes_in = 0; /* # of bytes to read */ - h5_log_io_ret_t bytes_read = -1; /* # of bytes actually read */ + h5_posix_io_t bytes_in = 0; /* # of bytes to read */ + h5_posix_io_ret_t bytes_read = -1; /* # of bytes actually read */ /* Trying to read more bytes than the return type can handle is * undefined behavior in POSIX. */ - if(size > H5_LOG_MAX_IO_BYTES_g) - bytes_in = H5_LOG_MAX_IO_BYTES_g; + if(size > H5_POSIX_MAX_IO_BYTES) + bytes_in = H5_POSIX_MAX_IO_BYTES; else - bytes_in = (h5_log_io_t)size; + bytes_in = (h5_posix_io_t)size; do { bytes_read = HDread(file->fd, buf, bytes_in); @@ -1258,7 +1233,7 @@ H5FD_log_read(H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id, haddr_t addr if(file->fa.flags & H5FD_LOG_LOC_READ) HDfprintf(file->logfp, "Error! Reading: %10a-%10a (%10Zu bytes)\n", orig_addr, (orig_addr + orig_size) - 1, orig_size); - HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed: time = %s, filename = '%s', file descriptor = %d, errno = %d, error message = '%s', buf = %p, size = %lu, offset = %llu", HDctime(&mytime), file->filename, file->fd, myerrno, HDstrerror(myerrno), buf, (unsigned long)size, (unsigned long long)myoffset); + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed: time = %s, filename = '%s', file descriptor = %d, errno = %d, error message = '%s', buf = %p, total read size = %llu, bytes this sub-read = %llu, bytes actually read = %llu, offset = %llu", HDctime(&mytime), file->filename, file->fd, myerrno, HDstrerror(myerrno), buf, (unsigned long long)size, (unsigned long long)bytes_in, (unsigned long long)bytes_read, (unsigned long long)myoffset); } /* end if */ if(0 == bytes_read) { @@ -1329,26 +1304,24 @@ done: /*------------------------------------------------------------------------- - * Function: H5FD_log_write + * Function: H5FD_log_write * - * Purpose: Writes SIZE bytes of data to FILE beginning at address ADDR - * from buffer BUF according to data transfer properties in - * DXPL_ID. + * Purpose: Writes SIZE bytes of data to FILE beginning at address ADDR + * from buffer BUF according to data transfer properties in + * DXPL_ID. * - * Return: Success: Zero - * Failure: -1 + * Return: SUCCEED/FAIL * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- */ -/* ARGSUSED */ static herr_t H5FD_log_write(H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id, haddr_t addr, - size_t size, const void *buf) + size_t size, const void *buf) { - H5FD_log_t *file = (H5FD_log_t *)_file; + H5FD_log_t *file = (H5FD_log_t *)_file; size_t orig_size = size; /* Save the original size for later */ haddr_t orig_addr = addr; #ifdef H5_HAVE_GETTIMEOFDAY @@ -1441,16 +1414,16 @@ H5FD_log_write(H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id, haddr_t add #endif /* H5_HAVE_GETTIMEOFDAY */ while(size > 0) { - h5_log_io_t bytes_in = 0; /* # of bytes to write */ - h5_log_io_ret_t bytes_wrote = -1; /* # of bytes written */ + h5_posix_io_t bytes_in = 0; /* # of bytes to write */ + h5_posix_io_ret_t bytes_wrote = -1; /* # of bytes written */ /* Trying to write more bytes than the return type can handle is * undefined behavior in POSIX. */ - if(size > H5_LOG_MAX_IO_BYTES_g) - bytes_in = H5_LOG_MAX_IO_BYTES_g; + if(size > H5_POSIX_MAX_IO_BYTES) + bytes_in = H5_POSIX_MAX_IO_BYTES; else - bytes_in = (h5_log_io_t)size; + bytes_in = (h5_posix_io_t)size; do { bytes_wrote = HDwrite(file->fd, buf, bytes_in); @@ -1464,7 +1437,7 @@ H5FD_log_write(H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id, haddr_t add if(file->fa.flags & H5FD_LOG_LOC_WRITE) HDfprintf(file->logfp, "Error! Writing: %10a-%10a (%10Zu bytes)\n", orig_addr, (orig_addr + orig_size) - 1, orig_size); - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed: time = %s, filename = '%s', file descriptor = %d, errno = %d, error message = '%s', buf = %p, size = %lu, offset = %llu", HDctime(&mytime), file->filename, file->fd, myerrno, HDstrerror(myerrno), buf, (unsigned long)size, (unsigned long long)myoffset); + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed: time = %s, filename = '%s', file descriptor = %d, errno = %d, error message = '%s', buf = %p, total write size = %llu, bytes this sub-write = %llu, bytes actually written = %llu, offset = %llu", HDctime(&mytime), file->filename, file->fd, myerrno, HDstrerror(myerrno), buf, (unsigned long long)size, (unsigned long long)bytes_in, (unsigned long long)bytes_wrote, (unsigned long long)myoffset); } /* end if */ HDassert(bytes_wrote > 0); @@ -1534,25 +1507,23 @@ done: /*------------------------------------------------------------------------- - * Function: H5FD_log_truncate + * Function: H5FD_log_truncate * - * Purpose: Makes sure that the true file size is the same (or larger) - * than the end-of-address. + * Purpose: Makes sure that the true file size is the same (or larger) + * than the end-of-address. * - * Return: Success: Non-negative - * Failure: Negative + * Return: SUCCEED/FAIL * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Wednesday, August 4, 1999 * *------------------------------------------------------------------------- */ -/* ARGSUSED */ static herr_t H5FD_log_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t UNUSED closing) { - H5FD_log_t *file = (H5FD_log_t *)_file; - herr_t ret_value = SUCCEED; /* Return value */ + H5FD_log_t *file = (H5FD_log_t *)_file; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -1613,4 +1584,3 @@ H5FD_log_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t UNUSED closing) done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD_log_truncate() */ - diff --git a/src/H5FDmpi.c b/src/H5FDmpi.c index 866a2cf..295e3c9f 100644 --- a/src/H5FDmpi.c +++ b/src/H5FDmpi.c @@ -29,11 +29,6 @@ #include "H5FDmpi.h" /* Common MPI file driver */ #include "H5Pprivate.h" /* Property lists */ -/* - * The view is set to this value - */ -char H5FD_mpi_native_g[] = "native"; - #ifdef H5_HAVE_PARALLEL diff --git a/src/H5FDmpi.h b/src/H5FDmpi.h index 4140671..dcb8df9 100644 --- a/src/H5FDmpi.h +++ b/src/H5FDmpi.h @@ -55,62 +55,9 @@ typedef enum H5FD_mpio_collective_opt_t { H5FD_MPIO_INDIVIDUAL_IO /*zero is the default*/ } H5FD_mpio_collective_opt_t; - -#ifdef H5_HAVE_PARALLEL - -/* Sub-class the H5FD_class_t to add more specific functions for MPI-based VFDs */ -typedef struct H5FD_class_mpi_t { - H5FD_class_t super; /* Superclass information & methods */ - int (*get_rank)(const H5FD_t *file); /* Get the MPI rank of a process */ - int (*get_size)(const H5FD_t *file); /* Get the MPI size of a communicator */ - MPI_Comm (*get_comm)(const H5FD_t *file); /* Get the communicator for a file */ -} H5FD_class_mpi_t; -#endif /* H5_HAVE_PARALLEL */ - /* Include all the MPI VFL headers */ #include "H5FDmpio.h" /* MPI I/O file driver */ #include "H5FDmpiposix.h" /* MPI/posix I/O file driver */ -/* Macros */ - -#ifdef H5_HAVE_PARALLEL -/* ======== Temporary data transfer properties ======== */ -/* Definitions for memory MPI type property */ -#define H5FD_MPI_XFER_MEM_MPI_TYPE_NAME "H5FD_mpi_mem_mpi_type" -/* Definitions for file MPI type property */ -#define H5FD_MPI_XFER_FILE_MPI_TYPE_NAME "H5FD_mpi_file_mpi_type" - -/* - * The view is set to this value - */ -H5_DLLVAR char H5FD_mpi_native_g[]; - -/* Function prototypes */ -#ifdef __cplusplus -extern "C" { -#endif -/* General routines */ -H5_DLL haddr_t H5FD_mpi_MPIOff_to_haddr(MPI_Offset mpi_off); -H5_DLL herr_t H5FD_mpi_haddr_to_MPIOff(haddr_t addr, MPI_Offset *mpi_off/*out*/); -H5_DLL herr_t H5FD_mpi_comm_info_dup(MPI_Comm comm, MPI_Info info, - MPI_Comm *comm_new, MPI_Info *info_new); -H5_DLL herr_t H5FD_mpi_comm_info_free(MPI_Comm *comm, MPI_Info *info); -#ifdef NOT_YET -H5_DLL herr_t H5FD_mpio_wait_for_left_neighbor(H5FD_t *file); -H5_DLL herr_t H5FD_mpio_signal_right_neighbor(H5FD_t *file); -#endif /* NOT_YET */ -H5_DLL herr_t H5FD_mpi_setup_collective(hid_t dxpl_id, MPI_Datatype *btype, - MPI_Datatype *ftype); - -/* Driver specific methods */ -H5_DLL int H5FD_mpi_get_rank(const H5FD_t *file); -H5_DLL int H5FD_mpi_get_size(const H5FD_t *file); -H5_DLL MPI_Comm H5FD_mpi_get_comm(const H5FD_t *_file); -#ifdef __cplusplus -} -#endif - -#endif /* H5_HAVE_PARALLEL */ - #endif /* H5FDmpi_H */ diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index 2db77c9..878bf82 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -45,6 +45,11 @@ static hid_t H5FD_MPIO_g = 0; /* + * The view is set to this value + */ +static char H5FD_mpi_native_g[] = "native"; + +/* * The description of a file belonging to this driver. * The EOF value is only used just after the file is opened in order for the * library to determine whether the file is empty, truncated, or okay. The MPIO diff --git a/src/H5FDmpio.h b/src/H5FDmpio.h index fe2d11f..d836086 100644 --- a/src/H5FDmpio.h +++ b/src/H5FDmpio.h @@ -30,9 +30,6 @@ /* Macros */ -#define IS_H5FD_MPIO(f) /* (H5F_t *f) */ \ - (H5FD_MPIO==H5F_DRIVER_ID(f)) - #ifdef H5_HAVE_PARALLEL /*Turn on H5FDmpio_debug if H5F_DEBUG is on */ #ifdef H5F_DEBUG diff --git a/src/H5FDmpiposix.c b/src/H5FDmpiposix.c index 88a5886..b1d68f6 100644 --- a/src/H5FDmpiposix.c +++ b/src/H5FDmpiposix.c @@ -71,21 +71,6 @@ */ static hid_t H5FD_MPIPOSIX_g = 0; -/* Since Windows doesn't follow the rest of the world when it comes - * to POSIX I/O types, some typedefs and constants are needed to avoid - * making the code messy with #ifdefs. - */ -#ifdef H5_HAVE_WIN32_API -typedef unsigned int h5_mpiposix_io_t; -typedef int h5_mpiposix_io_ret_t; -static int H5_MPIPOSIX_MAX_IO_BYTES_g = INT_MAX; -#else -/* Unix, everyone else */ -typedef size_t h5_mpiposix_io_t; -typedef ssize_t h5_mpiposix_io_ret_t; -static size_t H5_MPIPOSIX_MAX_IO_BYTES_g = SSIZET_MAX; -#endif /* H5_HAVE_WIN32_API */ - /* * The description of a file belonging to this driver. * The EOF value is only used just after the file is opened in order for the @@ -241,19 +226,16 @@ static const H5FD_class_mpi_t H5FD_mpiposix_g = { }; -/*-------------------------------------------------------------------------- -NAME - H5FD_mpiposix_init_interface -- Initialize interface-specific information -USAGE - herr_t H5FD_mpiposix_init_interface() - -RETURNS - Non-negative on success/Negative on failure -DESCRIPTION - Initializes any interface-specific data or routines. (Just calls - H5FD_mpiposix_init currently). - ---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------- + * Function: H5FD_mpiposix_init_interface + * + * Purpose: Initializes any interface-specific data or routines. + * + * Return: Success: The driver ID for the mpiposix driver. + * Failure: Negative. + * + *------------------------------------------------------------------------- + */ static herr_t H5FD_mpiposix_init_interface(void) { @@ -1094,16 +1076,16 @@ H5FD_mpiposix_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, */ while(size > 0) { - h5_mpiposix_io_t bytes_in = 0; /* # of bytes to read */ - h5_mpiposix_io_ret_t bytes_read = -1; /* # of bytes actually read */ + h5_posix_io_t bytes_in = 0; /* # of bytes to read */ + h5_posix_io_ret_t bytes_read = -1; /* # of bytes actually read */ /* Trying to read more bytes than the return type can handle is * undefined behavior in POSIX. */ - if(size > H5_MPIPOSIX_MAX_IO_BYTES_g) - bytes_in = H5_MPIPOSIX_MAX_IO_BYTES_g; + if(size > H5_POSIX_MAX_IO_BYTES) + bytes_in = H5_POSIX_MAX_IO_BYTES; else - bytes_in = (h5_mpiposix_io_t)size; + bytes_in = (h5_posix_io_t)size; do { bytes_read = HDread(file->fd, buf, bytes_in); @@ -1114,7 +1096,7 @@ H5FD_mpiposix_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, time_t mytime = HDtime(NULL); HDoff_t myoffset = HDlseek(file->fd, (HDoff_t)0, SEEK_CUR); - HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed: time = %s, file descriptor = %d, errno = %d, error message = '%s', buf = %p, size = %lu, offset = %llu", HDctime(&mytime), file->fd, myerrno, HDstrerror(myerrno), buf, (unsigned long)size, (unsigned long long)myoffset); + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed: time = %s, file descriptor = %d, errno = %d, error message = '%s', buf = %p, total read size = %llu, bytes this sub-read = %llu, bytes actually read = %llu, offset = %llu", HDctime(&mytime), file->fd, myerrno, HDstrerror(myerrno), buf, (unsigned long long)size, (unsigned long long)bytes_in, (unsigned long long)bytes_read, (unsigned long long)myoffset); } /* end if */ if(0 == bytes_read) { @@ -1278,16 +1260,16 @@ H5FD_mpiposix_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, */ while(size > 0) { - h5_mpiposix_io_t bytes_in = 0; /* # of bytes to write */ - h5_mpiposix_io_ret_t bytes_wrote = -1; /* # of bytes actually written */ + h5_posix_io_t bytes_in = 0; /* # of bytes to write */ + h5_posix_io_ret_t bytes_wrote = -1; /* # of bytes actually written */ /* Trying to write more bytes than the return type can handle is * undefined behavior in POSIX. */ - if(size > H5_MPIPOSIX_MAX_IO_BYTES_g) - bytes_in = H5_MPIPOSIX_MAX_IO_BYTES_g; + if(size > H5_POSIX_MAX_IO_BYTES) + bytes_in = H5_POSIX_MAX_IO_BYTES; else - bytes_in = (h5_mpiposix_io_t)size; + bytes_in = (h5_posix_io_t)size; do { bytes_wrote = HDwrite(file->fd, buf, bytes_in); @@ -1298,7 +1280,7 @@ H5FD_mpiposix_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, time_t mytime = HDtime(NULL); HDoff_t myoffset = HDlseek(file->fd, (HDoff_t)0, SEEK_CUR); - HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file write failed: time = %s, file descriptor = %d, errno = %d, error message = '%s', buf = %p, size = %lu, offset = %llu", HDctime(&mytime), file->fd, myerrno, HDstrerror(myerrno), buf, (unsigned long)size, (unsigned long long)myoffset); + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file write failed: time = %s, file descriptor = %d, errno = %d, error message = '%s', buf = %p, total write size = %llu, bytes this sub-write = %llu, bytes actually written = %llu, offset = %llu", HDctime(&mytime), file->fd, myerrno, HDstrerror(myerrno), buf, (unsigned long long)size, (unsigned long long)bytes_in, (unsigned long long)bytes_wrote, (unsigned long long)myoffset); } /* end if */ if(0 == bytes_wrote) { diff --git a/src/H5FDmpiposix.h b/src/H5FDmpiposix.h index e3764e1..12ff206 100644 --- a/src/H5FDmpiposix.h +++ b/src/H5FDmpiposix.h @@ -31,9 +31,6 @@ /* Macros */ -#define IS_H5FD_MPIPOSIX(f) /* (H5F_t *f) */ \ - (H5FD_MPIPOSIX==H5F_DRIVER_ID(f)) - #ifdef H5_HAVE_PARALLEL /* Function prototypes */ diff --git a/src/H5FDmulti.c b/src/H5FDmulti.c index 16934e3..5bdfbbe 100644 --- a/src/H5FDmulti.c +++ b/src/H5FDmulti.c @@ -77,6 +77,7 @@ #define H5FD_MULTI_DXPL_PROP_NAME "H5FD_MULTI_DXPL" #define H5FD_MULTI_DXPL_PROP_SIZE sizeof(H5FD_multi_dxpl_t) +#define H5FD_MULT_MAX_FILE_NAME_LEN 1024 /* The driver identification number, initialized at runtime */ static hid_t H5FD_MULTI_g = 0; @@ -207,12 +208,14 @@ static char * my_strdup(const char *s) { char *x; + size_t str_len; if(!s) return NULL; - if(NULL == (x = (char *)malloc(strlen(s) + 1))) + str_len = strlen(s) + 1; + if(NULL == (x = (char *)malloc(str_len))) return NULL; - strcpy(x, s); + memcpy(x, s, str_len); return x; } @@ -301,7 +304,7 @@ H5Pset_fapl_split(hid_t fapl, const char *meta_ext, hid_t meta_plist_id, H5FD_mem_t memb_map[H5FD_MEM_NTYPES]; hid_t memb_fapl[H5FD_MEM_NTYPES]; const char *memb_name[H5FD_MEM_NTYPES]; - char meta_name[1024], raw_name[1024]; + char meta_name[H5FD_MULT_MAX_FILE_NAME_LEN], raw_name[H5FD_MULT_MAX_FILE_NAME_LEN]; haddr_t memb_addr[H5FD_MEM_NTYPES]; /*NO TRACE*/ @@ -324,25 +327,39 @@ H5Pset_fapl_split(hid_t fapl, const char *meta_ext, hid_t meta_plist_id, /* The names */ /* process meta filename */ - if (meta_ext){ - if (strstr(meta_ext, "%s")) - strcpy(meta_name, meta_ext); + if(meta_ext) { + if(strstr(meta_ext, "%s")) { + /* Note: this doesn't accommodate for when the '%s' in the user's + * string is at a position >sizeof(meta_name) - QK & JK - 2013/01/17 + */ + strncpy(meta_name, meta_ext, sizeof(meta_name)); + meta_name[sizeof(meta_name) - 1] = '\0'; + } else sprintf(meta_name, "%%s%s", meta_ext); } - else - strcpy(meta_name, "%s.meta"); + else { + strncpy(meta_name, "%s.meta", sizeof(meta_name)); + meta_name[sizeof(meta_name) - 1] = '\0'; + } memb_name[H5FD_MEM_SUPER] = meta_name; /* process raw filename */ - if (raw_ext){ - if (strstr(raw_ext, "%s")) - strcpy(raw_name, raw_ext); + if(raw_ext) { + if(strstr(raw_ext, "%s")) { + /* Note: this doesn't accommodate for when the '%s' in the user's + * string is at a position >sizeof(raw_name) - QK & JK - 2013/01/17 + */ + strncpy(raw_name, raw_ext, sizeof(raw_name)); + raw_name[sizeof(raw_name) - 1] = '\0'; + } else sprintf(raw_name, "%%s%s", raw_ext); } - else - strcpy(raw_name, "%s.raw"); + else { + strncpy(raw_name, "%s.raw", sizeof(raw_name)); + raw_name[sizeof(raw_name) - 1] = '\0'; + } memb_name[H5FD_MEM_DRAW] = raw_name; /* The sizes */ @@ -573,12 +590,11 @@ H5Pget_fapl_multi(hid_t fapl_id, H5FD_mem_t *memb_map/*out*/, memb_fapl[mt] = fa->memb_fapl[mt]; /*default or bad ID*/ } } - if (memb_name) { - for (mt=H5FD_MEM_DEFAULT; mt<H5FD_MEM_NTYPES; mt=(H5FD_mem_t)(mt+1)) { - if (fa->memb_name[mt]) { - memb_name[mt] = (char *)malloc(strlen(fa->memb_name[mt])+1); - strcpy(memb_name[mt], fa->memb_name[mt]); - } else + if(memb_name) { + for(mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt = (H5FD_mem_t)(mt + 1)) { + if(fa->memb_name[mt]) + memb_name[mt] = my_strdup(fa->memb_name[mt]); + else memb_name[mt] = NULL; } } @@ -969,17 +985,17 @@ H5FD_multi_sb_encode(H5FD_t *_file, char *name/*out*/, p += sizeof(haddr_t); nseen++; } END_MEMBERS; - if (H5Tconvert(H5T_NATIVE_HADDR, H5T_STD_U64LE, nseen*2, buf+8, NULL, - H5P_DEFAULT)<0) + if (H5Tconvert(H5T_NATIVE_HADDR, H5T_STD_U64LE, nseen*2, buf+8, NULL, H5P_DEFAULT)<0) H5Epush_ret(func, H5E_ERR_CLS, H5E_DATATYPE, H5E_CANTCONVERT, "can't convert superblock info", -1) /* Encode all name templates */ p = buf + 8 + nseen*2*8; UNIQUE_MEMBERS(file->fa.memb_map, mt) { size_t n = strlen(file->fa.memb_name[mt]) + 1; - strcpy((char *)p, file->fa.memb_name[mt]); + strncpy((char *)p, file->fa.memb_name[mt], n); p += n; - for (i=n; i%8; i++) *p++ = '\0'; + for (i=n; i%8; i++) + *p++ = '\0'; } END_MEMBERS; return 0; @@ -1209,19 +1225,21 @@ H5FD_multi_fapl_copy(const void *_old_fa) ALL_MEMBERS(mt) { if (old_fa->memb_fapl[mt]>=0) { new_fa->memb_fapl[mt] = H5Pcopy(old_fa->memb_fapl[mt]); - if (new_fa->memb_fapl[mt]<0) nerrors++; + if(new_fa->memb_fapl[mt]<0) + nerrors++; } if (old_fa->memb_name[mt]) { - new_fa->memb_name[mt] = (char *)malloc(strlen(old_fa->memb_name[mt])+1); + new_fa->memb_name[mt] = my_strdup(old_fa->memb_name[mt]); assert(new_fa->memb_name[mt]); - strcpy(new_fa->memb_name[mt], old_fa->memb_name[mt]); } } END_MEMBERS; if (nerrors) { ALL_MEMBERS(mt) { - if (new_fa->memb_fapl[mt]>=0) (void)H5Pclose(new_fa->memb_fapl[mt]); - if (new_fa->memb_name[mt]) free(new_fa->memb_name[mt]); + if (new_fa->memb_fapl[mt]>=0) + (void)H5Pclose(new_fa->memb_fapl[mt]); + if (new_fa->memb_name[mt]) + free(new_fa->memb_name[mt]); } END_MEMBERS; free(new_fa); H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_BADVALUE, "invalid freespace objects", NULL) @@ -2191,7 +2209,7 @@ compute_next(H5FD_multi_t *file) static int open_members(H5FD_multi_t *file) { - char tmp[1024]; + char tmp[H5FD_MULT_MAX_FILE_NAME_LEN]; int nerrors=0; static const char *func="(H5FD_multi)open_members"; /* Function Name for error reporting */ @@ -2199,30 +2217,28 @@ open_members(H5FD_multi_t *file) H5Eclear2(H5E_DEFAULT); UNIQUE_MEMBERS(file->fa.memb_map, mt) { - if (file->memb[mt]) continue; /*already open*/ + if(file->memb[mt]) + continue; /*already open*/ assert(file->fa.memb_name[mt]); + /* Note: This truncates the user's filename down to only sizeof(tmp) + * characters. -QK & JK, 2013/01/17 + */ sprintf(tmp, file->fa.memb_name[mt], file->name); #ifdef H5FD_MULTI_DEBUG - if (file->flags & H5F_ACC_DEBUG) { - fprintf(stderr, "H5FD_MULTI: open member %d \"%s\"\n", - (int)mt, tmp); - } + if(file->flags & H5F_ACC_DEBUG) + fprintf(stderr, "H5FD_MULTI: open member %d \"%s\"\n", (int)mt, tmp); #endif H5E_BEGIN_TRY { - file->memb[mt] = H5FDopen(tmp, file->flags, file->fa.memb_fapl[mt], - HADDR_UNDEF); + file->memb[mt] = H5FDopen(tmp, file->flags, file->fa.memb_fapl[mt], HADDR_UNDEF); } H5E_END_TRY; - if (!file->memb[mt]) { + if(!file->memb[mt]) { #ifdef H5FD_MULTI_DEBUG - if (file->flags & H5F_ACC_DEBUG) { - fprintf(stderr, "H5FD_MULTI: open failed for member %d\n", - (int)mt); - } + if(file->flags & H5F_ACC_DEBUG) + fprintf(stderr, "H5FD_MULTI: open failed for member %d\n", (int)mt); #endif - if (!file->fa.relax || (file->flags & H5F_ACC_RDWR)) { + if(!file->fa.relax || (file->flags & H5F_ACC_RDWR)) nerrors++; - } } } END_MEMBERS; if (nerrors) diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h index 64b71d4..600cae1 100644 --- a/src/H5FDprivate.h +++ b/src/H5FDprivate.h @@ -39,6 +39,28 @@ /* Length of filename buffer */ #define H5FD_MAX_FILENAME_LEN 1024 +/* MPI based VFDs */ +#define IS_H5FD_MPIO(f) /* (H5F_t *f) */ \ + (H5FD_MPIO==H5F_DRIVER_ID(f)) + +#define IS_H5FD_MPIPOSIX(f) /* (H5F_t *f) */ \ + (H5FD_MPIPOSIX==H5F_DRIVER_ID(f)) + +#ifdef H5_HAVE_PARALLEL +/* ======== Temporary data transfer properties ======== */ +/* Definitions for memory MPI type property */ +#define H5FD_MPI_XFER_MEM_MPI_TYPE_NAME "H5FD_mpi_mem_mpi_type" +/* Definitions for file MPI type property */ +#define H5FD_MPI_XFER_FILE_MPI_TYPE_NAME "H5FD_mpi_file_mpi_type" + +/* Sub-class the H5FD_class_t to add more specific functions for MPI-based VFDs */ +typedef struct H5FD_class_mpi_t { + H5FD_class_t super; /* Superclass information & methods */ + int (*get_rank)(const H5FD_t *file); /* Get the MPI rank of a process */ + int (*get_size)(const H5FD_t *file); /* Get the MPI size of a communicator */ + MPI_Comm (*get_comm)(const H5FD_t *file); /* Get the communicator for a file */ +} H5FD_class_mpi_t; +#endif /****************************/ /* Library Private Typedefs */ @@ -123,9 +145,28 @@ H5_DLL herr_t H5FD_get_fileno(const H5FD_t *file, unsigned long *filenum); H5_DLL herr_t H5FD_get_vfd_handle(H5FD_t *file, hid_t fapl, void** file_handle); H5_DLL herr_t H5FD_set_base_addr(H5FD_t *file, haddr_t base_addr); H5_DLL haddr_t H5FD_get_base_addr(const H5FD_t *file); + +/* Function prototypes for MPI based VFDs*/ #ifdef H5_HAVE_PARALLEL +/* General routines */ +H5_DLL haddr_t H5FD_mpi_MPIOff_to_haddr(MPI_Offset mpi_off); +H5_DLL herr_t H5FD_mpi_haddr_to_MPIOff(haddr_t addr, MPI_Offset *mpi_off/*out*/); +H5_DLL herr_t H5FD_mpi_comm_info_dup(MPI_Comm comm, MPI_Info info, + MPI_Comm *comm_new, MPI_Info *info_new); +H5_DLL herr_t H5FD_mpi_comm_info_free(MPI_Comm *comm, MPI_Info *info); +#ifdef NOT_YET +H5_DLL herr_t H5FD_mpio_wait_for_left_neighbor(H5FD_t *file); +H5_DLL herr_t H5FD_mpio_signal_right_neighbor(H5FD_t *file); +#endif /* NOT_YET */ +H5_DLL herr_t H5FD_mpi_setup_collective(hid_t dxpl_id, MPI_Datatype *btype, + MPI_Datatype *ftype); H5_DLL herr_t H5FD_set_mpio_atomicity(H5FD_t *file, hbool_t flag); H5_DLL herr_t H5FD_get_mpio_atomicity(H5FD_t *file, hbool_t *flag); + +/* Driver specific methods */ +H5_DLL int H5FD_mpi_get_rank(const H5FD_t *file); +H5_DLL int H5FD_mpi_get_size(const H5FD_t *file); +H5_DLL MPI_Comm H5FD_mpi_get_comm(const H5FD_t *_file); #endif /* H5_HAVE_PARALLEL */ #endif /* !_H5FDprivate_H */ diff --git a/src/H5FDsec2.c b/src/H5FDsec2.c index afe745b..86ef6c6 100644 --- a/src/H5FDsec2.c +++ b/src/H5FDsec2.c @@ -17,56 +17,41 @@ * Programmer: Robb Matzke <matzke@llnl.gov> * Thursday, July 29, 1999 * - * Purpose: The POSIX unbuffered file driver using only the HDF5 public - * API and with a few optimizations: the lseek() call is made - * only when the current file position is unknown or needs to be - * changed based on previous I/O through this driver (don't mix - * I/O from this driver with I/O from other parts of the - * application to the same file). + * Purpose: The POSIX unbuffered file driver using only the HDF5 public + * API and with a few optimizations: the lseek() call is made + * only when the current file position is unknown or needs to be + * changed based on previous I/O through this driver (don't mix + * I/O from this driver with I/O from other parts of the + * application to the same file). */ /* Interface initialization */ -#define H5_INTERFACE_INIT_FUNC H5FD_sec2_init_interface +#define H5_INTERFACE_INIT_FUNC H5FD_sec2_init_interface -#include "H5private.h" /* Generic Functions */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5Fprivate.h" /* File access */ -#include "H5FDprivate.h" /* File drivers */ -#include "H5FDsec2.h" /* Sec2 file driver */ -#include "H5FLprivate.h" /* Free Lists */ -#include "H5Iprivate.h" /* IDs */ -#include "H5MMprivate.h" /* Memory management */ -#include "H5Pprivate.h" /* Property lists */ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fprivate.h" /* File access */ +#include "H5FDprivate.h" /* File drivers */ +#include "H5FDsec2.h" /* Sec2 file driver */ +#include "H5FLprivate.h" /* Free Lists */ +#include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Pprivate.h" /* Property lists */ /* The driver identification number, initialized at runtime */ static hid_t H5FD_SEC2_g = 0; -/* Since Windows doesn't follow the rest of the world when it comes - * to POSIX I/O types, some typedefs and constants are needed to avoid - * making the code messy with #ifdefs. - */ -#ifdef H5_HAVE_WIN32_API -typedef unsigned int h5_sec2_io_t; -typedef int h5_sec2_io_ret_t; -static int H5_SEC2_MAX_IO_BYTES_g = INT_MAX; -#else -/* Unix, everyone else */ -typedef size_t h5_sec2_io_t; -typedef ssize_t h5_sec2_io_ret_t; -static size_t H5_SEC2_MAX_IO_BYTES_g = SSIZET_MAX; -#endif /* H5_HAVE_WIN32_API */ - -/* The description of a file belonging to this driver. The `eoa' and `eof' +/* The description of a file belonging to this driver. The 'eoa' and 'eof' * determine the amount of hdf5 address space in use and the high-water mark * of the file (the current size of the underlying filesystem file). The - * `pos' value is used to eliminate file position updates when they would be a + * 'pos' value is used to eliminate file position updates when they would be a * no-op. Unfortunately we've found systems that use separate file position * indicators for reading and writing so the lseek can only be eliminated if * the current operation is the same as the previous operation. When opening - * a file the `eof' will be set to the current file size, `eoa' will be set - * to zero, `pos' will be set to H5F_ADDR_UNDEF (as it is when an error - * occurs), and `op' will be set to H5F_OP_UNKNOWN. + * a file the 'eof' will be set to the current file size, `eoa' will be set + * to zero, 'pos' will be set to H5F_ADDR_UNDEF (as it is when an error + * occurs), and 'op' will be set to H5F_OP_UNKNOWN. */ typedef struct H5FD_sec2_t { H5FD_t pub; /* public stuff, must be first */ @@ -129,29 +114,28 @@ typedef struct H5FD_sec2_t { * These macros check for overflow of various quantities. These macros * assume that HDoff_t is signed and haddr_t and size_t are unsigned. * - * ADDR_OVERFLOW: Checks whether a file address of type `haddr_t' - * is too large to be represented by the second argument - * of the file seek function. + * ADDR_OVERFLOW: Checks whether a file address of type `haddr_t' + * is too large to be represented by the second argument + * of the file seek function. * - * SIZE_OVERFLOW: Checks whether a buffer size of type `hsize_t' is too - * large to be represented by the `size_t' type. + * SIZE_OVERFLOW: Checks whether a buffer size of type `hsize_t' is too + * large to be represented by the `size_t' type. * - * REGION_OVERFLOW: Checks whether an address and size pair describe data - * which can be addressed entirely by the second - * argument of the file seek function. + * REGION_OVERFLOW: Checks whether an address and size pair describe data + * which can be addressed entirely by the second + * argument of the file seek function. */ #define MAXADDR (((haddr_t)1<<(8*sizeof(HDoff_t)-1))-1) -#define ADDR_OVERFLOW(A) (HADDR_UNDEF==(A) || \ - ((A) & ~(haddr_t)MAXADDR)) -#define SIZE_OVERFLOW(Z) ((Z) & ~(hsize_t)MAXADDR) -#define REGION_OVERFLOW(A,Z) (ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) || \ - HADDR_UNDEF==(A)+(Z) || \ - (HDoff_t)((A)+(Z))<(HDoff_t)(A)) +#define ADDR_OVERFLOW(A) (HADDR_UNDEF==(A) || ((A) & ~(haddr_t)MAXADDR)) +#define SIZE_OVERFLOW(Z) ((Z) & ~(hsize_t)MAXADDR) +#define REGION_OVERFLOW(A,Z) (ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) || \ + HADDR_UNDEF==(A)+(Z) || \ + (HDoff_t)((A)+(Z))<(HDoff_t)(A)) /* Prototypes */ static herr_t H5FD_sec2_term(void); static H5FD_t *H5FD_sec2_open(const char *name, unsigned flags, hid_t fapl_id, - haddr_t maxaddr); + haddr_t maxaddr); static herr_t H5FD_sec2_close(H5FD_t *_file); static int H5FD_sec2_cmp(const H5FD_t *_f1, const H5FD_t *_f2); static herr_t H5FD_sec2_query(const H5FD_t *_f1, unsigned long *flags); @@ -160,63 +144,60 @@ static herr_t H5FD_sec2_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr); static haddr_t H5FD_sec2_get_eof(const H5FD_t *_file); static herr_t H5FD_sec2_get_handle(H5FD_t *_file, hid_t fapl, void** file_handle); static herr_t H5FD_sec2_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, - size_t size, void *buf); + size_t size, void *buf); static herr_t H5FD_sec2_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, - size_t size, const void *buf); + size_t size, const void *buf); static herr_t H5FD_sec2_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); static const H5FD_class_t H5FD_sec2_g = { - "sec2", /*name */ - MAXADDR, /*maxaddr */ - H5F_CLOSE_WEAK, /* fc_degree */ - H5FD_sec2_term, /*terminate */ - NULL, /*sb_size */ - NULL, /*sb_encode */ - NULL, /*sb_decode */ - 0, /*fapl_size */ - NULL, /*fapl_get */ - NULL, /*fapl_copy */ - NULL, /*fapl_free */ - 0, /*dxpl_size */ - NULL, /*dxpl_copy */ - NULL, /*dxpl_free */ - H5FD_sec2_open, /*open */ - H5FD_sec2_close, /*close */ - H5FD_sec2_cmp, /*cmp */ - H5FD_sec2_query, /*query */ - NULL, /*get_type_map */ - NULL, /*alloc */ - NULL, /*free */ - H5FD_sec2_get_eoa, /*get_eoa */ - H5FD_sec2_set_eoa, /*set_eoa */ - H5FD_sec2_get_eof, /*get_eof */ - H5FD_sec2_get_handle, /*get_handle */ - H5FD_sec2_read, /*read */ - H5FD_sec2_write, /*write */ - NULL, /*flush */ - H5FD_sec2_truncate, /*truncate */ - NULL, /*lock */ - NULL, /*unlock */ - H5FD_FLMAP_DICHOTOMY /*fl_map */ + "sec2", /* name */ + MAXADDR, /* maxaddr */ + H5F_CLOSE_WEAK, /* fc_degree */ + H5FD_sec2_term, /* terminate */ + NULL, /* sb_size */ + NULL, /* sb_encode */ + NULL, /* sb_decode */ + 0, /* fapl_size */ + NULL, /* fapl_get */ + NULL, /* fapl_copy */ + NULL, /* fapl_free */ + 0, /* dxpl_size */ + NULL, /* dxpl_copy */ + NULL, /* dxpl_free */ + H5FD_sec2_open, /* open */ + H5FD_sec2_close, /* close */ + H5FD_sec2_cmp, /* cmp */ + H5FD_sec2_query, /* query */ + NULL, /* get_type_map */ + NULL, /* alloc */ + NULL, /* free */ + H5FD_sec2_get_eoa, /* get_eoa */ + H5FD_sec2_set_eoa, /* set_eoa */ + H5FD_sec2_get_eof, /* get_eof */ + H5FD_sec2_get_handle, /* get_handle */ + H5FD_sec2_read, /* read */ + H5FD_sec2_write, /* write */ + NULL, /* flush */ + H5FD_sec2_truncate, /* truncate */ + NULL, /* lock */ + NULL, /* unlock */ + H5FD_FLMAP_DICHOTOMY /* fl_map */ }; /* Declare a free list to manage the H5FD_sec2_t struct */ H5FL_DEFINE_STATIC(H5FD_sec2_t); -/*-------------------------------------------------------------------------- -NAME - H5FD_sec2_init_interface -- Initialize interface-specific information -USAGE - herr_t H5FD_sec2_init_interface() - -RETURNS - Non-negative on success/Negative on failure -DESCRIPTION - Initializes any interface-specific data or routines. (Just calls - H5FD_sec2_init currently). - ---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------- + * Function: H5FD_sec2_init_interface + * + * Purpose: Initializes any interface-specific data or routines. + * + * Return: Success: The driver ID for the sec2 driver. + * Failure: Negative + * + *------------------------------------------------------------------------- + */ static herr_t H5FD_sec2_init_interface(void) { @@ -227,15 +208,15 @@ H5FD_sec2_init_interface(void) /*------------------------------------------------------------------------- - * Function: H5FD_sec2_init + * Function: H5FD_sec2_init * - * Purpose: Initialize this driver by registering the driver with the - * library. + * Purpose: Initialize this driver by registering the driver with the + * library. * - * Return: Success: The driver ID for the sec2 driver. - * Failure: Negative. + * Return: Success: The driver ID for the sec2 driver. + * Failure: Negative * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- @@ -259,11 +240,11 @@ done: /*--------------------------------------------------------------------------- - * Function: H5FD_sec2_term + * Function: H5FD_sec2_term * - * Purpose: Shut down the VFD + * Purpose: Shut down the VFD * - * Returns: Non-negative on success or negative on failure + * Returns: SUCCEED (Can't fail) * * Programmer: Quincey Koziol * Friday, Jan 30, 2004 @@ -283,16 +264,16 @@ H5FD_sec2_term(void) /*------------------------------------------------------------------------- - * Function: H5Pset_fapl_sec2 + * Function: H5Pset_fapl_sec2 * - * Purpose: Modify the file access property list to use the H5FD_SEC2 - * driver defined in this source file. There are no driver - * specific properties. + * Purpose: Modify the file access property list to use the H5FD_SEC2 + * driver defined in this source file. There are no driver + * specific properties. * - * Return: Non-negative on success/Negative on failure + * Return: SUCCEED/FAIL * - * Programmer: Robb Matzke - * Thursday, February 19, 1998 + * Programmer: Robb Matzke + * Thursday, February 19, 1998 * *------------------------------------------------------------------------- */ @@ -316,16 +297,16 @@ done: /*------------------------------------------------------------------------- - * Function: H5FD_sec2_open + * Function: H5FD_sec2_open * - * Purpose: Create and/or opens a file as an HDF5 file. + * Purpose: Create and/or opens a file as an HDF5 file. * - * Return: Success: A pointer to a new file data structure. The - * public fields will be initialized by the - * caller, which is always H5FD_open(). - * Failure: NULL + * Return: Success: A pointer to a new file data structure. The + * public fields will be initialized by the + * caller, which is always H5FD_open(). + * Failure: NULL * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- @@ -445,14 +426,14 @@ done: /*------------------------------------------------------------------------- - * Function: H5FD_sec2_close + * Function: H5FD_sec2_close * - * Purpose: Closes an HDF5 file. + * Purpose: Closes an HDF5 file. * - * Return: Success: 0 - * Failure: -1, file not closed. + * Return: Success: SUCCEED + * Failure: FAIL, file not closed. * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- @@ -460,8 +441,8 @@ done: static herr_t H5FD_sec2_close(H5FD_t *_file) { - H5FD_sec2_t *file = (H5FD_sec2_t *)_file; - herr_t ret_value = SUCCEED; /* Return value */ + H5FD_sec2_t *file = (H5FD_sec2_t *)_file; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -481,16 +462,16 @@ done: /*------------------------------------------------------------------------- - * Function: H5FD_sec2_cmp + * Function: H5FD_sec2_cmp * - * Purpose: Compares two files belonging to this driver using an - * arbitrary (but consistent) ordering. + * Purpose: Compares two files belonging to this driver using an + * arbitrary (but consistent) ordering. * - * Return: Success: A value like strcmp() - * Failure: never fails (arguments were checked by the - * caller). + * Return: Success: A value like strcmp() + * Failure: never fails (arguments were checked by the + * caller). * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- @@ -498,8 +479,8 @@ done: static int H5FD_sec2_cmp(const H5FD_t *_f1, const H5FD_t *_f2) { - const H5FD_sec2_t *f1 = (const H5FD_sec2_t *)_f1; - const H5FD_sec2_t *f2 = (const H5FD_sec2_t *)_f2; + const H5FD_sec2_t *f1 = (const H5FD_sec2_t *)_f1; + const H5FD_sec2_t *f2 = (const H5FD_sec2_t *)_f2; int ret_value = 0; FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -540,15 +521,14 @@ done: /*------------------------------------------------------------------------- - * Function: H5FD_sec2_query + * Function: H5FD_sec2_query * - * Purpose: Set the flags that this VFL driver is capable of supporting. + * Purpose: Set the flags that this VFL driver is capable of supporting. * (listed in H5FDpublic.h) * - * Return: Success: non-negative - * Failure: negative + * Return: SUCCEED (Can't fail) * - * Programmer: Quincey Koziol + * Programmer: Quincey Koziol * Friday, August 25, 2000 * *------------------------------------------------------------------------- @@ -579,21 +559,19 @@ H5FD_sec2_query(const H5FD_t *_file, unsigned long *flags /* out */) /*------------------------------------------------------------------------- - * Function: H5FD_sec2_get_eoa + * Function: H5FD_sec2_get_eoa * - * Purpose: Gets the end-of-address marker for the file. The EOA marker - * is the first address past the last byte allocated in the - * format address space. + * Purpose: Gets the end-of-address marker for the file. The EOA marker + * is the first address past the last byte allocated in the + * format address space. * - * Return: Success: The end-of-address marker. - * Failure: HADDR_UNDEF + * Return: The end-of-address marker. * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Monday, August 2, 1999 * *------------------------------------------------------------------------- */ -/* ARGSUSED */ static haddr_t H5FD_sec2_get_eoa(const H5FD_t *_file, H5FD_mem_t UNUSED type) { @@ -606,21 +584,19 @@ H5FD_sec2_get_eoa(const H5FD_t *_file, H5FD_mem_t UNUSED type) /*------------------------------------------------------------------------- - * Function: H5FD_sec2_set_eoa + * Function: H5FD_sec2_set_eoa * - * Purpose: Set the end-of-address marker for the file. This function is - * called shortly after an existing HDF5 file is opened in order - * to tell the driver where the end of the HDF5 data is located. + * Purpose: Set the end-of-address marker for the file. This function is + * called shortly after an existing HDF5 file is opened in order + * to tell the driver where the end of the HDF5 data is located. * - * Return: Success: 0 - * Failure: -1 + * Return: SUCCEED (Can't fail) * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- */ -/* ARGSUSED */ static herr_t H5FD_sec2_set_eoa(H5FD_t *_file, H5FD_mem_t UNUSED type, haddr_t addr) { @@ -635,18 +611,16 @@ H5FD_sec2_set_eoa(H5FD_t *_file, H5FD_mem_t UNUSED type, haddr_t addr) /*------------------------------------------------------------------------- - * Function: H5FD_sec2_get_eof + * Function: H5FD_sec2_get_eof * - * Purpose: Returns the end-of-file marker, which is the greater of - * either the filesystem end-of-file or the HDF5 end-of-address - * markers. + * Purpose: Returns the end-of-file marker, which is the greater of + * either the filesystem end-of-file or the HDF5 end-of-address + * markers. * - * Return: Success: End of file address, the first address past - * the end of the "file", either the filesystem file - * or the HDF5 file. - * Failure: HADDR_UNDEF + * Return: End of file address, the first address past the end of the + * "file", either the filesystem file or the HDF5 file. * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- @@ -654,7 +628,7 @@ H5FD_sec2_set_eoa(H5FD_t *_file, H5FD_mem_t UNUSED type, haddr_t addr) static haddr_t H5FD_sec2_get_eof(const H5FD_t *_file) { - const H5FD_sec2_t *file = (const H5FD_sec2_t *)_file; + const H5FD_sec2_t *file = (const H5FD_sec2_t *)_file; FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -667,14 +641,13 @@ H5FD_sec2_get_eof(const H5FD_t *_file) * * Purpose: Returns the file handle of sec2 file driver. * - * Returns: Non-negative if succeed or negative if fails. + * Returns: SUCCEED/FAIL * * Programmer: Raymond Lu * Sept. 16, 2002 * *------------------------------------------------------------------------- */ -/* ARGSUSED */ static herr_t H5FD_sec2_get_handle(H5FD_t *_file, hid_t UNUSED fapl, void **file_handle) { @@ -694,22 +667,21 @@ done: /*------------------------------------------------------------------------- - * Function: H5FD_sec2_read + * Function: H5FD_sec2_read * - * Purpose: Reads SIZE bytes of data from FILE beginning at address ADDR - * into buffer BUF according to data transfer properties in - * DXPL_ID. + * Purpose: Reads SIZE bytes of data from FILE beginning at address ADDR + * into buffer BUF according to data transfer properties in + * DXPL_ID. * - * Return: Success: Zero. Result is stored in caller-supplied - * buffer BUF. - * Failure: -1, Contents of buffer BUF are undefined. + * Return: Success: SUCCEED. Result is stored in caller-supplied + * buffer BUF. + * Failure: FAIL, Contents of buffer BUF are undefined. * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- */ -/* ARGSUSED */ static herr_t H5FD_sec2_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr, size_t size, void *buf /*out*/) @@ -748,16 +720,16 @@ H5FD_sec2_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, */ while(size > 0) { - h5_sec2_io_t bytes_in = 0; /* # of bytes to read */ - h5_sec2_io_ret_t bytes_read = -1; /* # of bytes actually read */ + h5_posix_io_t bytes_in = 0; /* # of bytes to read */ + h5_posix_io_ret_t bytes_read = -1; /* # of bytes actually read */ /* Trying to read more bytes than the return type can handle is * undefined behavior in POSIX. */ - if(size > H5_SEC2_MAX_IO_BYTES_g) - bytes_in = H5_SEC2_MAX_IO_BYTES_g; + if(size > H5_POSIX_MAX_IO_BYTES) + bytes_in = H5_POSIX_MAX_IO_BYTES; else - bytes_in = (h5_sec2_io_t)size; + bytes_in = (h5_posix_io_t)size; do { bytes_read = HDread(file->fd, buf, bytes_in); @@ -768,7 +740,7 @@ H5FD_sec2_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, time_t mytime = HDtime(NULL); HDoff_t myoffset = HDlseek(file->fd, (HDoff_t)0, SEEK_CUR); - HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed: time = %s, filename = '%s', file descriptor = %d, errno = %d, error message = '%s', buf = %p, size = %lu, offset = %llu", HDctime(&mytime), file->filename, file->fd, myerrno, HDstrerror(myerrno), buf, (unsigned long)size, (unsigned long long)myoffset); + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed: time = %s, filename = '%s', file descriptor = %d, errno = %d, error message = '%s', buf = %p, total read size = %llu, bytes this sub-read = %llu, bytes actually read = %llu, offset = %llu", HDctime(&mytime), file->filename, file->fd, myerrno, HDstrerror(myerrno), buf, (unsigned long long)size, (unsigned long long)bytes_in, (unsigned long long)bytes_read, (unsigned long long)myoffset); } /* end if */ if(0 == bytes_read) { @@ -801,21 +773,19 @@ done: /*------------------------------------------------------------------------- - * Function: H5FD_sec2_write + * Function: H5FD_sec2_write * - * Purpose: Writes SIZE bytes of data to FILE beginning at address ADDR - * from buffer BUF according to data transfer properties in - * DXPL_ID. + * Purpose: Writes SIZE bytes of data to FILE beginning at address ADDR + * from buffer BUF according to data transfer properties in + * DXPL_ID. * - * Return: Success: Zero - * Failure: -1 + * Return: SUCCEED/FAIL * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Thursday, July 29, 1999 * *------------------------------------------------------------------------- */ -/* ARGSUSED */ static herr_t H5FD_sec2_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr, size_t size, const void *buf) @@ -847,16 +817,16 @@ H5FD_sec2_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, */ while(size > 0) { - h5_sec2_io_t bytes_in = 0; /* # of bytes to write */ - h5_sec2_io_ret_t bytes_wrote = -1; /* # of bytes written */ + h5_posix_io_t bytes_in = 0; /* # of bytes to write */ + h5_posix_io_ret_t bytes_wrote = -1; /* # of bytes written */ /* Trying to write more bytes than the return type can handle is * undefined behavior in POSIX. */ - if(size > H5_SEC2_MAX_IO_BYTES_g) - bytes_in = H5_SEC2_MAX_IO_BYTES_g; + if(size > H5_POSIX_MAX_IO_BYTES) + bytes_in = H5_POSIX_MAX_IO_BYTES; else - bytes_in = (h5_sec2_io_t)size; + bytes_in = (h5_posix_io_t)size; do { bytes_wrote = HDwrite(file->fd, buf, bytes_in); @@ -867,7 +837,7 @@ H5FD_sec2_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, time_t mytime = HDtime(NULL); HDoff_t myoffset = HDlseek(file->fd, (HDoff_t)0, SEEK_CUR); - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed: time = %s, filename = '%s', file descriptor = %d, errno = %d, error message = '%s', buf = %p, size = %lu, offset = %llu", HDctime(&mytime), file->filename, file->fd, myerrno, HDstrerror(myerrno), buf, (unsigned long)size, (unsigned long long)myoffset); + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed: time = %s, filename = '%s', file descriptor = %d, errno = %d, error message = '%s', buf = %p, total write size = %llu, bytes this sub-write = %llu, bytes actually written = %llu, offset = %llu", HDctime(&mytime), file->filename, file->fd, myerrno, HDstrerror(myerrno), buf, (unsigned long long)size, (unsigned long long)bytes_in, (unsigned long long)bytes_wrote, (unsigned long long)myoffset); } /* end if */ HDassert(bytes_wrote > 0); @@ -896,20 +866,18 @@ done: /*------------------------------------------------------------------------- - * Function: H5FD_sec2_truncate + * Function: H5FD_sec2_truncate * - * Purpose: Makes sure that the true file size is the same (or larger) - * than the end-of-address. + * Purpose: Makes sure that the true file size is the same (or larger) + * than the end-of-address. * - * Return: Success: Non-negative - * Failure: Negative + * Return: SUCCEED/FAIL * - * Programmer: Robb Matzke + * Programmer: Robb Matzke * Wednesday, August 4, 1999 * *------------------------------------------------------------------------- */ -/* ARGSUSED */ static herr_t H5FD_sec2_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t UNUSED closing) { @@ -970,4 +938,3 @@ H5FD_sec2_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t UNUSED closing) done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD_sec2_truncate() */ - diff --git a/src/H5FDstdio.c b/src/H5FDstdio.c index 6dbc515..9b1dbf9 100644 --- a/src/H5FDstdio.c +++ b/src/H5FDstdio.c @@ -368,26 +368,35 @@ H5FD_stdio_open( const char *name, unsigned flags, hid_t fapl_id, if (ADDR_OVERFLOW(maxaddr)) H5Epush_ret(func, H5E_ERR_CLS, H5E_ARGS, H5E_OVERFLOW, "maxaddr too large", NULL) - /* Attempt to open/create the file */ - if (access(name, F_OK) < 0) { - if ((flags & H5F_ACC_CREAT) && (flags & H5F_ACC_RDWR)) { + /* Tentatively open file in read-only mode, to check for existence */ + if(flags & H5F_ACC_RDWR) + f = fopen(name, "rb+"); + else + f = fopen(name, "rb"); + + if(!f) { + /* File doesn't exist */ + if(flags & H5F_ACC_CREAT) { + assert(flags & H5F_ACC_RDWR); f = fopen(name, "wb+"); write_access = 1; /* Note the write access */ } else H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_CANTOPENFILE, "file doesn't exist and CREAT wasn't specified", NULL) - } else if ((flags & H5F_ACC_CREAT) && (flags & H5F_ACC_EXCL)) { + } else if(flags & H5F_ACC_EXCL) { + /* File exists, but EXCL is passed. Fail. */ + assert(flags & H5F_ACC_CREAT); + fclose(f); H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_FILEEXISTS, "file exists but CREAT and EXCL were specified", NULL) - } else if (flags & H5F_ACC_RDWR) { - if (flags & H5F_ACC_TRUNC) - f = fopen(name, "wb+"); - else - f = fopen(name, "rb+"); + } else if(flags & H5F_ACC_RDWR) { + if(flags & H5F_ACC_TRUNC) + f = freopen(name, "wb+", f); write_access = 1; /* Note the write access */ - } else { - f = fopen(name, "rb"); - } - if (!f) + } /* end if */ + /* Note there is no need to reopen if neither TRUNC nor EXCL are specified, + * as the tentative open will work */ + + if(!f) H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_CANTOPENFILE, "fopen failed", NULL) /* Build the return value */ @@ -409,23 +418,36 @@ H5FD_stdio_open( const char *name, unsigned flags, hid_t fapl_id, /* Get the file descriptor (needed for truncate and some Windows information) */ file->fd = fileno(file->fp); - if(file->fd < 0) + if(file->fd < 0) { + free(file); + fclose(f); H5Epush_ret(func, H5E_ERR_CLS, H5E_FILE, H5E_CANTOPENFILE, "unable to get file descriptor", NULL); + } /* end if */ #ifdef H5_HAVE_WIN32_API file->hFile = (HANDLE)_get_osfhandle(file->fd); - if(INVALID_HANDLE_VALUE == file->hFile) + if(INVALID_HANDLE_VALUE == file->hFile) { + free(file); + fclose(f); H5Epush_ret(func, H5E_ERR_CLS, H5E_FILE, H5E_CANTOPENFILE, "unable to get Windows file handle", NULL); + } /* end if */ - if(!GetFileInformationByHandle((HANDLE)file->hFile, &fileinfo)) - H5Epush_ret(func, H5E_ERR_CLS, H5E_FILE, H5E_CANTOPENFILE, "unable to get Windows file desinformationcriptor", NULL); + if(!GetFileInformationByHandle((HANDLE)file->hFile, &fileinfo)) { + free(file); + fclose(f); + H5Epush_ret(func, H5E_ERR_CLS, H5E_FILE, H5E_CANTOPENFILE, "unable to get Windows file descriptor information", NULL); + } /* end if */ file->nFileIndexHigh = fileinfo.nFileIndexHigh; file->nFileIndexLow = fileinfo.nFileIndexLow; file->dwVolumeSerialNumber = fileinfo.dwVolumeSerialNumber; #else /* H5_HAVE_WIN32_API */ - fstat(file->fd, &sb); + if(fstat(file->fd, &sb) < 0) { + free(file); + fclose(f); + H5Epush_ret(func, H5E_ERR_CLS, H5E_FILE, H5E_BADFILE, "unable to fstat file", NULL) + } /* end if */ file->device = sb.st_dev; #ifdef H5_VMS file->inode[0] = sb.st_ino[0]; diff --git a/src/H5Fmpi.c b/src/H5Fmpi.c index 966528a..07d29f2 100644 --- a/src/H5Fmpi.c +++ b/src/H5Fmpi.c @@ -37,7 +37,6 @@ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fpkg.h" /* File access */ -#include "H5FDmpi.h" /* MPI-based file drivers */ #include "H5FDprivate.h" /* File drivers */ #include "H5Iprivate.h" /* IDs */ diff --git a/src/H5Gint.c b/src/H5Gint.c index ad2e57e..fe8b995 100644 --- a/src/H5Gint.c +++ b/src/H5Gint.c @@ -928,7 +928,7 @@ H5G_visit_cb(const H5O_link_t *lnk, void *_udata) /* Build the link's relative path name */ HDassert(udata->path[old_path_len] == '\0'); - HDstrcpy(&(udata->path[old_path_len]), lnk->name); + HDstrncpy(&(udata->path[old_path_len]), lnk->name, link_name_len + 1); udata->curr_path_len += link_name_len; /* Construct the link info from the link message */ @@ -992,7 +992,7 @@ H5G_visit_cb(const H5O_link_t *lnk, void *_udata) /* Add the path separator to the current path */ HDassert(udata->path[udata->curr_path_len] == '\0'); - HDstrcpy(&(udata->path[udata->curr_path_len]), "/"); + HDstrncpy(&(udata->path[udata->curr_path_len]), "/", 2); udata->curr_path_len++; /* Attempt to get the link info for this group */ diff --git a/src/H5Gname.c b/src/H5Gname.c index 576d866..72da498 100644 --- a/src/H5Gname.c +++ b/src/H5Gname.c @@ -293,7 +293,9 @@ static H5RS_str_t * H5G_build_fullpath(const char *prefix, const char *name) { char *full_path; /* Full user path built */ + size_t orig_path_len; /* Original length of the path */ size_t path_len; /* Length of the path */ + size_t name_len; /* Length of the name */ unsigned need_sep; /* Flag to indicate if separator is needed */ H5RS_str_t *ret_value; /* Return value */ @@ -304,7 +306,7 @@ H5G_build_fullpath(const char *prefix, const char *name) HDassert(name); /* Get the length of the prefix */ - path_len = HDstrlen(prefix); + orig_path_len = path_len = HDstrlen(prefix); /* Determine if there is a trailing separator in the name */ if(prefix[path_len - 1] == '/') @@ -313,20 +315,21 @@ H5G_build_fullpath(const char *prefix, const char *name) need_sep = 1; /* Add in the length needed for the '/' separator and the relative path */ - path_len += HDstrlen(name) + need_sep; + name_len = HDstrlen(name); + path_len += name_len + need_sep; /* Allocate space for the path */ if(NULL == (full_path = (char *)H5FL_BLK_MALLOC(str_buf, path_len + 1))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Build full path */ - HDstrcpy(full_path, prefix); + HDstrncpy(full_path, prefix, orig_path_len + 1); if(need_sep) - HDstrcat(full_path, "/"); - HDstrcat(full_path, name); + HDstrncat(full_path, "/", 1); + HDstrncat(full_path, name, name_len); /* Create reference counted string for path */ - if((ret_value = H5RS_own(full_path)) == NULL) + if(NULL == (ret_value = H5RS_own(full_path))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") done: @@ -423,7 +426,7 @@ H5G_build_fullpath_refstr_refstr(const H5RS_str_t *prefix_r, const H5RS_str_t *n herr_t H5G__name_init(H5G_name_t *name, const char *path) { - FUNC_ENTER_PACKAGE + FUNC_ENTER_PACKAGE_NOERR /* Check arguments */ HDassert(name); @@ -717,6 +720,7 @@ H5G_name_move_path(H5RS_str_t **path_r_ptr, const char *full_suffix, const char path_len = HDstrlen(path); if(full_suffix_len < path_len) { const char *dst_suffix; /* Destination suffix that changes */ + size_t dst_suffix_len; /* Length of destination suffix */ const char *src_suffix; /* Source suffix that changes */ size_t path_prefix_len; /* Length of path prefix */ const char *path_prefix2; /* 2nd prefix for path */ @@ -747,25 +751,26 @@ H5G_name_move_path(H5RS_str_t **path_r_ptr, const char *full_suffix, const char /* Determine destination suffix */ dst_suffix = dst_path + (common_prefix_len - 1); + dst_suffix_len = HDstrlen(dst_suffix); /* Compute path prefix before src suffix*/ path_prefix2 = path; path_prefix2_len = path_prefix_len - HDstrlen(src_suffix); /* Allocate space for the new path */ - new_path_len = path_prefix2_len + HDstrlen(dst_suffix) + full_suffix_len; + new_path_len = path_prefix2_len + dst_suffix_len + full_suffix_len; if(NULL == (new_path = (char *)H5FL_BLK_MALLOC(str_buf, new_path_len + 1))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") /* Create the new path */ if(path_prefix2_len > 0) { - HDstrncpy(new_path, path_prefix2, path_prefix2_len); - HDstrcpy(new_path + path_prefix2_len, dst_suffix); + HDstrncpy(new_path, path_prefix2, path_prefix2_len + 1); + HDstrncpy(new_path + path_prefix2_len, dst_suffix, dst_suffix_len + 1); } /* end if */ else - HDstrcpy(new_path, dst_suffix); + HDstrncpy(new_path, dst_suffix, dst_suffix_len + 1); if(full_suffix_len > 0) - HDstrcat(new_path, full_suffix); + HDstrncat(new_path, full_suffix, full_suffix_len); /* Release previous path */ H5RS_decr(*path_r_ptr); @@ -887,23 +892,25 @@ H5G_name_replace_cb(void *obj_ptr, hid_t obj_id, void *key) if(obj_in_child) { const char *full_path; /* Full path of current object */ const char *src_path; /* Full path of source object */ + size_t src_path_len; /* Length of source full path */ char *new_full_path; /* New full path of object */ size_t new_full_len; /* Length of new full path */ /* Get pointers to paths of interest */ full_path = H5RS_get_str(obj_path->full_path_r); src_path = H5RS_get_str(names->src_full_path_r); + src_path_len = HDstrlen(src_path); /* Build new full path */ /* Allocate space for the new full path */ - new_full_len = HDstrlen(src_path) + HDstrlen(full_path); + new_full_len = src_path_len + HDstrlen(full_path); if(NULL == (new_full_path = (char *)H5FL_BLK_MALLOC(str_buf, new_full_len + 1))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") /* Create the new full path */ - HDstrcpy(new_full_path, src_path); - HDstrcat(new_full_path, full_path); + HDstrncpy(new_full_path, src_path, src_path_len + 1); + HDstrncat(new_full_path, full_path, new_full_len); /* Release previous full path */ H5RS_decr(obj_path->full_path_r); @@ -931,6 +938,7 @@ H5G_name_replace_cb(void *obj_ptr, hid_t obj_id, void *key) if(obj_in_child) { const char *full_path; /* Full path of current object */ const char *full_suffix; /* Full path after source path */ + size_t full_suffix_len; /* Length of full path after source path */ const char *src_path; /* Full path of source object */ char *new_full_path; /* New full path of object */ @@ -940,13 +948,14 @@ H5G_name_replace_cb(void *obj_ptr, hid_t obj_id, void *key) /* Construct full path suffix */ full_suffix = full_path + HDstrlen(src_path); + full_suffix_len = HDstrlen(full_suffix); /* Build new full path */ /* Create the new full path */ - if(NULL == (new_full_path = (char *)H5FL_BLK_MALLOC(str_buf, HDstrlen(full_suffix) + 1))) + if(NULL == (new_full_path = (char *)H5FL_BLK_MALLOC(str_buf, full_suffix_len + 1))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - HDstrcpy(new_full_path, full_suffix); + HDstrncpy(new_full_path, full_suffix, full_suffix_len + 1); /* Release previous full path */ H5RS_decr(obj_path->full_path_r); @@ -992,10 +1001,12 @@ H5G_name_replace_cb(void *obj_ptr, hid_t obj_id, void *key) if(H5G_common_path(obj_path->full_path_r, names->src_full_path_r)) { const char *full_path; /* Full path of current object */ const char *full_suffix; /* Suffix of full path, after src_path */ + size_t full_suffix_len; /* Length of suffix of full path after src_path*/ char *new_full_path; /* New full path of object */ size_t new_full_len; /* Length of new full path */ const char *src_path; /* Full path of source object */ const char *dst_path; /* Full path of destination object */ + size_t dst_path_len; /* Length of destination's full path */ /* Sanity check */ HDassert(names->dst_full_path_r); @@ -1004,6 +1015,7 @@ H5G_name_replace_cb(void *obj_ptr, hid_t obj_id, void *key) full_path = H5RS_get_str(obj_path->full_path_r); src_path = H5RS_get_str(names->src_full_path_r); dst_path = H5RS_get_str(names->dst_full_path_r); + dst_path_len = HDstrlen(dst_path); /* Make certain that the source and destination names are full (not relative) paths */ HDassert(*src_path == '/'); @@ -1011,6 +1023,7 @@ H5G_name_replace_cb(void *obj_ptr, hid_t obj_id, void *key) /* Get pointer to "full suffix" */ full_suffix = full_path + HDstrlen(src_path); + full_suffix_len = HDstrlen(full_suffix); /* Update the user path, if one exists */ if(obj_path->user_path_r) @@ -1020,13 +1033,13 @@ H5G_name_replace_cb(void *obj_ptr, hid_t obj_id, void *key) /* Build new full path */ /* Allocate space for the new full path */ - new_full_len = HDstrlen(dst_path) + HDstrlen(full_suffix); + new_full_len = dst_path_len + full_suffix_len; if(NULL == (new_full_path = (char *)H5FL_BLK_MALLOC(str_buf, new_full_len + 1))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") /* Create the new full path */ - HDstrcpy(new_full_path, dst_path); - HDstrcat(new_full_path, full_suffix); + HDstrncpy(new_full_path, dst_path, dst_path_len + 1); + HDstrncat(new_full_path, full_suffix, full_suffix_len); /* Release previous full path */ H5RS_decr(obj_path->full_path_r); @@ -1318,7 +1331,7 @@ H5G_get_name_by_addr(hid_t file, hid_t lapl_id, hid_t dxpl_id, const H5O_loc_t * /* If there's a buffer provided, copy into it, up to the limit of its size */ if(name) { /* Copy the initial path separator */ - HDstrcpy(name, "/"); + HDstrncpy(name, "/", 2); /* Append the rest of the path */ /* (less one character, for the initial path separator) */ diff --git a/src/H5Gtest.c b/src/H5Gtest.c index e83097e..ccfca9d 100644 --- a/src/H5Gtest.c +++ b/src/H5Gtest.c @@ -568,7 +568,7 @@ H5G__user_path_test(hid_t obj_id, char *user_path, size_t *user_path_len, unsign /* Set the user path, if given */ if(user_path) - HDstrcpy(user_path, H5RS_get_str(obj_path->user_path_r)); + HDstrncpy(user_path, H5RS_get_str(obj_path->user_path_r), (size_t)(len + 1)); /* Set the length of the path */ *user_path_len = (size_t)len; diff --git a/src/H5HFdbg.c b/src/H5HFdbg.c index 8d2b6fa..5d68fd1 100644 --- a/src/H5HFdbg.c +++ b/src/H5HFdbg.c @@ -381,7 +381,7 @@ H5HF_dblock_debug_cb(H5FS_section_info_t *_sect, void *_udata) size_t start, end; /* Start & end of the overlapping area */ size_t len; /* Length of the overlapping area */ size_t overlap; /* Track any overlaps */ - unsigned u; /* Local index variable */ + size_t u; /* Local index variable */ /* Calculate the starting & ending */ if(sect_start < dblock_start) @@ -396,7 +396,7 @@ H5HF_dblock_debug_cb(H5FS_section_info_t *_sect, void *_udata) /* Calculate the length */ len = end - start; - sprintf(temp_str, "Section #%u:", (unsigned)udata->sect_count); + HDsnprintf(temp_str, sizeof(temp_str), "Section #%u:", (unsigned)udata->sect_count); HDfprintf(udata->stream, "%*s%-*s %8Zu, %8Zu\n", udata->indent + 3, "", MAX(0, udata->fwidth - 9), temp_str, start, len); @@ -530,7 +530,7 @@ H5HF_dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, HDfprintf(stream, "%*s%-*s %.2f%%\n", indent, "", fwidth, "Percent of available space for data used:", - (100.0 * (double)((dblock->size - blk_prefix_size) - amount_free) / (double)(dblock->size - blk_prefix_size))); + ((double)100.0f * (double)((dblock->size - blk_prefix_size) - amount_free) / (double)(dblock->size - blk_prefix_size))); /* * Print the data in a VMS-style octal dump. @@ -614,13 +614,13 @@ H5HF_iblock_print(const H5HF_indirect_t *iblock, else HDfprintf(stream, "%*sDirect Block Entries: (address)\n", indent, ""); for(u = 0; u < hdr->man_dtable.max_direct_rows && u < iblock->nrows; u++) { - sprintf(temp_str, "Row #%u: (block size: %lu)", (unsigned)u, (unsigned long)hdr->man_dtable.row_block_size[u]); + HDsnprintf(temp_str, sizeof(temp_str), "Row #%u: (block size: %lu)", (unsigned)u, (unsigned long)hdr->man_dtable.row_block_size[u]); HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3), temp_str); for(v = 0; v < hdr->man_dtable.cparam.width; v++) { size_t off = (u * hdr->man_dtable.cparam.width) + v; - sprintf(temp_str, "Col #%u:", (unsigned)v); + HDsnprintf(temp_str, sizeof(temp_str), "Col #%u:", (unsigned)v); if(hdr->filter_len > 0) HDfprintf(stream, "%*s%-*s %9a/%6Zu/%x\n", indent + 6, "", MAX(0, fwidth - 6), temp_str, @@ -642,13 +642,13 @@ H5HF_iblock_print(const H5HF_indirect_t *iblock, H5V_log2_of2(hdr->man_dtable.cparam.width); for(u = hdr->man_dtable.max_direct_rows; u < iblock->nrows; u++) { num_indirect_rows = (H5V_log2_gen(hdr->man_dtable.row_block_size[u]) - first_row_bits) + 1; - sprintf(temp_str, "Row #%u: (# of rows: %u)", (unsigned)u, num_indirect_rows); + HDsnprintf(temp_str, sizeof(temp_str), "Row #%u: (# of rows: %u)", (unsigned)u, num_indirect_rows); HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3), temp_str); for(v = 0; v < hdr->man_dtable.cparam.width; v++) { size_t off = (u * hdr->man_dtable.cparam.width) + v; - sprintf(temp_str, "Col #%u:", (unsigned)v); + HDsnprintf(temp_str, sizeof(temp_str), "Col #%u:", (unsigned)v); HDfprintf(stream, "%*s%-*s %9a\n", indent + 6, "", MAX(0, fwidth - 6), temp_str, iblock->ents[off].addr); diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c index 365124d..2f42bf1 100644 --- a/src/H5Lexternal.c +++ b/src/H5Lexternal.c @@ -102,7 +102,7 @@ H5L_getenv_prefix_name(char **env_prefix/*in,out*/) FUNC_ENTER_NOAPI_NOINIT_NOERR - strret = HDstrchr(*env_prefix, COLON_SEPC); + strret = HDstrchr(*env_prefix, H5_COLON_SEPC); if (strret == NULL) { retptr = *env_prefix; *env_prefix = strret; @@ -144,14 +144,9 @@ H5L_build_name(char *prefix, char *file_name, char **full_name/*out*/) if(NULL == (*full_name = (char *)H5MM_malloc(prefix_len + fname_len + 2))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate filename buffer") - /* Copy the prefix into the buffer */ - HDstrcpy(*full_name, prefix); - - if (!CHECK_DELIMITER(prefix[prefix_len-1])) - HDstrcat(*full_name, DIR_SEPS); - - /* Add the external link's filename to the prefix supplied */ - HDstrcat(*full_name, file_name); + /* Compose the full file name */ + HDsnprintf(*full_name, (prefix_len + fname_len + 2), "%s%s%s", prefix, + (H5_CHECK_DELIMITER(prefix[prefix_len - 1]) ? "" : H5_DIR_SEPS), file_name); done: FUNC_LEAVE_NOAPI(ret_value) @@ -319,24 +314,32 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group, HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") /* target file_name is an absolute pathname: see RM for detailed description */ - if(CHECK_ABSOLUTE(file_name) || CHECK_ABS_PATH(file_name)) { + if(H5_CHECK_ABSOLUTE(file_name) || H5_CHECK_ABS_PATH(file_name)) { /* Try opening file */ if(NULL == (ext_file = H5F_efc_open(loc.oloc->file, file_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) { - char *ptr = NULL; + char *ptr; H5E_clear_stack(NULL); /* get last component of file_name */ - GET_LAST_DELIMITER(file_name, ptr) + H5_GET_LAST_DELIMITER(file_name, ptr) HDassert(ptr); - HDstrcpy(temp_file_name, ++ptr); + + /* Increment past delimiter */ + ptr++; + + /* Copy into the temp. file name */ + HDstrncpy(temp_file_name, ptr, HDstrlen(ptr) + 1); } /* end if */ } /* end if */ - else if(CHECK_ABS_DRIVE(file_name)) { + else if(H5_CHECK_ABS_DRIVE(file_name)) { + /* Try opening file */ if(NULL == (ext_file = H5F_efc_open(loc.oloc->file, file_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) { + H5E_clear_stack(NULL); + /* strip "<drive-letter>:" */ - HDstrcpy(temp_file_name, &file_name[2]); + HDstrncpy(temp_file_name, &file_name[2], (HDstrlen(file_name) - 2) + 1); } /* end if */ } /* end if */ @@ -414,7 +417,7 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group, HGOTO_ERROR(H5E_LINK, H5E_CANTALLOC, FAIL, "can't duplicate resolved file name string") /* get last component of file_name */ - GET_LAST_DELIMITER(actual_file_name, ptr) + H5_GET_LAST_DELIMITER(actual_file_name, ptr) if(!ptr) HGOTO_ERROR(H5E_LINK, H5E_CANTOPENFILE, FAIL, "unable to open external file, external link file name = '%s', temp_file_name = '%s'", file_name, temp_file_name) @@ -543,6 +546,8 @@ H5Lcreate_external(const char *file_name, const char *obj_name, char *norm_obj_name = NULL; /* Pointer to normalized current name */ void *ext_link_buf = NULL; /* Buffer to contain external link */ size_t buf_size; /* Size of buffer to hold external link */ + size_t file_name_len; /* Length of file name string */ + size_t norm_obj_name_len; /* Length of normalized object name string */ uint8_t *p; /* Pointer into external link buffer */ herr_t ret_value = SUCCEED; /* Return value */ @@ -565,16 +570,18 @@ H5Lcreate_external(const char *file_name, const char *obj_name, HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "can't normalize object name") /* Combine the filename and link name into a single buffer to give to the UD link */ - buf_size = 1 + (HDstrlen(file_name) + 1) + (HDstrlen(norm_obj_name) + 1); + file_name_len = HDstrlen(file_name) + 1; + norm_obj_name_len = HDstrlen(norm_obj_name) + 1; + buf_size = 1 + file_name_len + norm_obj_name_len; if(NULL == (ext_link_buf = H5MM_malloc(buf_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate udata buffer") /* Encode the external link information */ p = (uint8_t *)ext_link_buf; *p++ = (H5L_EXT_VERSION << 4) | H5L_EXT_FLAGS_ALL; /* External link version & flags */ - HDstrcpy((char *)p, file_name); /* Name of file containing external link's object */ - p += HDstrlen(file_name) + 1; - HDstrcpy((char *)p, norm_obj_name); /* External link's object */ + HDstrncpy((char *)p, file_name, file_name_len); /* Name of file containing external link's object */ + p += file_name_len; + HDstrncpy((char *)p, norm_obj_name, norm_obj_name_len); /* External link's object */ /* Create an external link */ if(H5L_create_ud(&link_loc, link_name, ext_link_buf, buf_size, H5L_TYPE_EXTERNAL, lcpl_id, lapl_id, H5AC_dxpl_id) < 0) diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c index d54f454..f131be2 100644 --- a/src/H5Ocopy.c +++ b/src/H5Ocopy.c @@ -1254,7 +1254,7 @@ H5O_copy_obj_by_ref(H5O_loc_t *src_oloc, hid_t dxpl_id, H5O_loc_t *dst_oloc, new_oloc.addr = dst_oloc->addr; /* Pick a default name for the new object */ - sprintf(tmp_obj_name, "~obj_pointed_by_%llu", (unsigned long long)dst_oloc->addr); + HDsnprintf(tmp_obj_name, sizeof(tmp_obj_name), "~obj_pointed_by_%llu", (unsigned long long)dst_oloc->addr); /* Create a link to the newly copied object */ /* Note: since H5O_copy_header_map actually copied the target object, it diff --git a/src/H5Oname.c b/src/H5Oname.c index fb44000..c1cb8c8 100644 --- a/src/H5Oname.c +++ b/src/H5Oname.c @@ -97,10 +97,10 @@ H5O_name_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh, HDassert(p); /* decode */ - if(NULL == (mesg = (H5O_name_t *)H5MM_calloc(sizeof(H5O_name_t))) || - NULL == (mesg->s = (char *)H5MM_malloc(HDstrlen((const char *)p) + 1))) + if(NULL == (mesg = (H5O_name_t *)H5MM_calloc(sizeof(H5O_name_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + if(NULL == (mesg->s = (char *)H5MM_strdup((const char *)p))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - HDstrcpy(mesg->s, (const char *)p); /* Set return value */ ret_value = mesg; @@ -138,9 +138,9 @@ H5O_name_encode(H5F_t UNUSED *f, hbool_t UNUSED disable_shared, uint8_t *p, cons FUNC_ENTER_NOAPI_NOINIT_NOERR /* check args */ - assert(f); - assert(p); - assert(mesg && mesg->s); + HDassert(f); + HDassert(p); + HDassert(mesg && mesg->s); /* encode */ HDstrcpy((char*)p, mesg->s); diff --git a/src/H5Pdxpl.c b/src/H5Pdxpl.c index ec7def8..4754aa5 100644 --- a/src/H5Pdxpl.c +++ b/src/H5Pdxpl.c @@ -158,6 +158,15 @@ #define H5D_XFER_XFORM_COPY H5P__dxfr_xform_copy #define H5D_XFER_XFORM_CMP H5P__dxfr_xform_cmp #define H5D_XFER_XFORM_CLOSE H5P__dxfr_xform_close +/* Definitions for properties of direct chunk write */ +#define H5D_XFER_DIRECT_CHUNK_WRITE_FLAG_SIZE sizeof(hbool_t) +#define H5D_XFER_DIRECT_CHUNK_WRITE_FLAG_DEF FALSE +#define H5D_XFER_DIRECT_CHUNK_WRITE_FILTERS_SIZE sizeof(uint32_t) +#define H5D_XFER_DIRECT_CHUNK_WRITE_FILTERS_DEF 0 +#define H5D_XFER_DIRECT_CHUNK_WRITE_OFFSET_SIZE sizeof(hsize_t *) +#define H5D_XFER_DIRECT_CHUNK_WRITE_OFFSET_DEF NULL +#define H5D_XFER_DIRECT_CHUNK_WRITE_DATASIZE_SIZE sizeof(size_t) +#define H5D_XFER_DIRECT_CHUNK_WRITE_DATASIZE_DEF 0 /******************/ /* Local Typedefs */ @@ -254,7 +263,10 @@ static const H5Z_EDC_t H5D_def_enable_edc_g = H5D_XFER_EDC_DEF; /* De static const H5Z_cb_t H5D_def_filter_cb_g = H5D_XFER_FILTER_CB_DEF; /* Default value for filter callback */ static const H5T_conv_cb_t H5D_def_conv_cb_g = H5D_XFER_CONV_CB_DEF; /* Default value for datatype conversion callback */ static const void *H5D_def_xfer_xform_g = H5D_XFER_XFORM_DEF; /* Default value for data transform */ - +static const hbool_t H5D_def_direct_chunk_flag_g = H5D_XFER_DIRECT_CHUNK_WRITE_FLAG_DEF; /* Default value for the flag of direct chunk write */ +static const uint32_t H5D_def_direct_chunk_filters_g = H5D_XFER_DIRECT_CHUNK_WRITE_FILTERS_DEF; /* Default value for the filters of direct chunk write */ +static const hsize_t *H5D_def_direct_chunk_offset_g = H5D_XFER_DIRECT_CHUNK_WRITE_OFFSET_DEF; /* Default value for the offset of direct chunk write */ +static const size_t H5D_def_direct_chunk_datasize_g = H5D_XFER_DIRECT_CHUNK_WRITE_DATASIZE_DEF; /* Default value for the datasize of direct chunk write */ /*------------------------------------------------------------------------- @@ -424,6 +436,30 @@ H5P__dxfr_reg_prop(H5P_genclass_t *pclass) H5D_XFER_XFORM_DEL, H5D_XFER_XFORM_COPY, H5D_XFER_XFORM_CMP, H5D_XFER_XFORM_CLOSE) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + /* Register the property of flag for direct chunk write */ + /* (Note: this property should not have an encode/decode callback -QAK) */ + if(H5P_register_real(pclass, H5D_XFER_DIRECT_CHUNK_WRITE_FLAG_NAME, H5D_XFER_DIRECT_CHUNK_WRITE_FLAG_SIZE, &H5D_def_direct_chunk_flag_g, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + + /* Register the property of filter for direct chunk write */ + /* (Note: this property should not have an encode/decode callback -QAK) */ + if(H5P_register_real(pclass, H5D_XFER_DIRECT_CHUNK_WRITE_FILTERS_NAME, H5D_XFER_DIRECT_CHUNK_WRITE_FILTERS_SIZE, &H5D_def_direct_chunk_filters_g, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + + /* Register the property of offset for direct chunk write */ + /* (Note: this property should not have an encode/decode callback -QAK) */ + if(H5P_register_real(pclass, H5D_XFER_DIRECT_CHUNK_WRITE_OFFSET_NAME, H5D_XFER_DIRECT_CHUNK_WRITE_OFFSET_SIZE, &H5D_def_direct_chunk_offset_g, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + + /* Register the property of datasize for direct chunk write */ + /* (Note: this property should not have an encode/decode callback -QAK) */ + if(H5P_register_real(pclass, H5D_XFER_DIRECT_CHUNK_WRITE_DATASIZE_NAME, H5D_XFER_DIRECT_CHUNK_WRITE_DATASIZE_SIZE, &H5D_def_direct_chunk_datasize_g, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5P__dxfr_reg_prop() */ @@ -4389,7 +4389,7 @@ H5T_path_find(const H5T_t *src, const H5T_t *dst, const char *name, H5T_g.apaths = 128; if(NULL == (H5T_g.path[0] = H5FL_CALLOC(H5T_path_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for no-op conversion path") - HDstrcpy(H5T_g.path[0]->name, "no-op"); + HDsnprintf(H5T_g.path[0]->name, sizeof(H5T_g.path[0]->name), "no-op"); H5T_g.path[0]->func = H5T__conv_noop; H5T_g.path[0]->cdata.command = H5T_CONV_INIT; if(H5T__conv_noop(FAIL, FAIL, &(H5T_g.path[0]->cdata), (size_t)0, (size_t)0, (size_t)0, NULL, NULL, dxpl_id) < 0) { @@ -4457,7 +4457,7 @@ H5T_path_find(const H5T_t *src, const H5T_t *dst, const char *name, path->name[H5T_NAMELEN - 1] = '\0'; } /* end if */ else - HDstrcpy(path->name, "NONAME"); + HDsnprintf(path->name, sizeof(path->name), "NONAME"); if(NULL == (path->src = H5T_copy(src, H5T_COPY_ALL))) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy datatype for conversion path") if(NULL == (path->dst = H5T_copy(dst, H5T_COPY_ALL))) diff --git a/src/H5config.h.in b/src/H5config.h.in index fdbcd49..0308b38 100644 --- a/src/H5config.h.in +++ b/src/H5config.h.in @@ -74,6 +74,9 @@ /* Define if the function stack tracing code is to be compiled in */ #undef HAVE_CODESTACK +/* Define if Darwin or Mac OS X */ +#undef HAVE_DARWIN + /* Define to 1 if you have the declaration of `tzname', and to 0 if you don't. */ #undef HAVE_DECL_TZNAME diff --git a/src/H5private.h b/src/H5private.h index b8b1754..711cea8 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -430,6 +430,24 @@ #define HSSIZET_MIN (~(HSSIZET_MAX)) /* + * Types and max sizes for POSIX I/O. + * OS X (Darwin) is odd since the max I/O size does not match the types. + */ +#if defined(H5_HAVE_WIN32_API) +# define h5_posix_io_t unsigned int +# define h5_posix_io_ret_t int +# define H5_POSIX_MAX_IO_BYTES INT_MAX +#elif defined(H5_HAVE_DARWIN) +# define h5_posix_io_t size_t +# define h5_posix_io_ret_t ssize_t +# define H5_POSIX_MAX_IO_BYTES INT_MAX +#else +# define h5_posix_io_t size_t +# define h5_posix_io_ret_t ssize_t +# define H5_POSIX_MAX_IO_BYTES SSIZET_MAX +#endif + +/* * A macro to portably increment enumerated types. */ #ifndef H5_INC_ENUM @@ -1455,19 +1473,20 @@ extern char *strdup(const char *s); #if defined(H5_HAVE_WINDOW_PATH) /* directory delimiter for Windows: slash and backslash are acceptable on Windows */ -#define DIR_SLASH_SEPC '/' -#define DIR_SEPC '\\' -#define DIR_SEPS "\\" -#define CHECK_DELIMITER(SS) ((SS == DIR_SEPC)||(SS == DIR_SLASH_SEPC)) -#define CHECK_ABSOLUTE(NAME) ((isalpha(NAME[0])) && (NAME[1] == ':') && (CHECK_DELIMITER(NAME[2]))) -#define CHECK_ABS_DRIVE(NAME) ((isalpha(NAME[0])) && (NAME[1] == ':')) -#define CHECK_ABS_PATH(NAME) (CHECK_DELIMITER(NAME[0])) - -#define GET_LAST_DELIMITER(NAME, ptr) { \ +#define H5_DIR_SLASH_SEPC '/' +#define H5_DIR_SEPC '\\' +#define H5_DIR_SEPS "\\" +#define H5_CHECK_DELIMITER(SS) ((SS == H5_DIR_SEPC) || (SS == H5_DIR_SLASH_SEPC)) +#define H5_CHECK_ABSOLUTE(NAME) ((HDisalpha(NAME[0])) && (NAME[1] == ':') && (H5_CHECK_DELIMITER(NAME[2]))) +#define H5_CHECK_ABS_DRIVE(NAME) ((HDisalpha(NAME[0])) && (NAME[1] == ':')) +#define H5_CHECK_ABS_PATH(NAME) (H5_CHECK_DELIMITER(NAME[0])) + +#define H5_GET_LAST_DELIMITER(NAME, ptr) { \ char *slash, *backslash; \ - slash = strrchr(NAME, DIR_SLASH_SEPC); \ - backslash = strrchr(NAME, DIR_SEPC); \ - if (backslash > slash) \ + \ + slash = HDstrrchr(NAME, H5_DIR_SLASH_SEPC); \ + backslash = HDstrrchr(NAME, H5_DIR_SEPC); \ + if(backslash > slash) \ (ptr = backslash); \ else \ (ptr = slash); \ @@ -1477,27 +1496,27 @@ extern char *strdup(const char *s); /* OpenVMS pathname: <disk name>$<partition>:[path]<file name> * i.g. SYS$SYSUSERS:[LU.HDF5.SRC]H5system.c */ -#define DIR_SEPC ']' -#define DIR_SEPS "]" -#define CHECK_DELIMITER(SS) (SS == DIR_SEPC) -#define CHECK_ABSOLUTE(NAME) (strrchr(NAME, ':') && strrchr(NAME, '[')) -#define CHECK_ABS_DRIVE(NAME) (0) -#define CHECK_ABS_PATH(NAME) (0) -#define GET_LAST_DELIMITER(NAME, ptr) ptr = strrchr(NAME, DIR_SEPC); +#define H5_DIR_SEPC ']' +#define H5_DIR_SEPS "]" +#define H5_CHECK_DELIMITER(SS) (SS == H5_DIR_SEPC) +#define H5_CHECK_ABSOLUTE(NAME) (HDstrrchr(NAME, ':') && HDstrrchr(NAME, '[')) +#define H5_CHECK_ABS_DRIVE(NAME) (0) +#define H5_CHECK_ABS_PATH(NAME) (0) +#define H5_GET_LAST_DELIMITER(NAME, ptr) ptr = HDstrrchr(NAME, H5_DIR_SEPC); #else -#define DIR_SEPC '/' -#define DIR_SEPS "/" -#define CHECK_DELIMITER(SS) (SS == DIR_SEPC) -#define CHECK_ABSOLUTE(NAME) (CHECK_DELIMITER(*NAME)) -#define CHECK_ABS_DRIVE(NAME) (0) -#define CHECK_ABS_PATH(NAME) (0) -#define GET_LAST_DELIMITER(NAME, ptr) ptr = strrchr(NAME, DIR_SEPC); +#define H5_DIR_SEPC '/' +#define H5_DIR_SEPS "/" +#define H5_CHECK_DELIMITER(SS) (SS == H5_DIR_SEPC) +#define H5_CHECK_ABSOLUTE(NAME) (H5_CHECK_DELIMITER(*NAME)) +#define H5_CHECK_ABS_DRIVE(NAME) (0) +#define H5_CHECK_ABS_PATH(NAME) (0) +#define H5_GET_LAST_DELIMITER(NAME, ptr) ptr = HDstrrchr(NAME, H5_DIR_SEPC); #endif -#define COLON_SEPC ':' +#define H5_COLON_SEPC ':' /* Use FUNC to safely handle variations of C99 __func__ keyword handling */ diff --git a/src/H5public.h b/src/H5public.h index 54cd0b6..0a4e9c0 100644 --- a/src/H5public.h +++ b/src/H5public.h @@ -75,10 +75,10 @@ extern "C" { /* Version numbers */ #define H5_VERS_MAJOR 1 /* For major interface/format changes */ #define H5_VERS_MINOR 9 /* For minor interface/format changes */ -#define H5_VERS_RELEASE 137 /* For tweaks, bug-fixes, or development */ +#define H5_VERS_RELEASE 148 /* For tweaks, bug-fixes, or development */ #define H5_VERS_SUBRELEASE "FA_a5" /* For pre-releases like snap0 */ /* Empty string for real releases. */ -#define H5_VERS_INFO "HDF5 library version: 1.9.137-FA_a5" /* Full version string */ +#define H5_VERS_INFO "HDF5 library version: 1.9.148-FA_a5" /* Full version string */ #define H5check() H5check_version(H5_VERS_MAJOR,H5_VERS_MINOR, \ H5_VERS_RELEASE) diff --git a/src/H5system.c b/src/H5system.c index c0baee1..3ffe411 100644 --- a/src/H5system.c +++ b/src/H5system.c @@ -122,24 +122,24 @@ HDfprintf(FILE *stream, const char *fmt, ...) va_start (ap, fmt); while (*fmt) { - fwidth = prec = 0; - zerofill = 0; - leftjust = 0; - plussign = 0; - prefix = 0; - ldspace = 0; - modifier[0] = '\0'; - - if ('%'==fmt[0] && '%'==fmt[1]) { - HDputc ('%', stream); - fmt += 2; - nout++; - } else if ('%'==fmt[0]) { - s = fmt + 1; - - /* Flags */ - while(HDstrchr ("-+ #", *s)) { - switch(*s) { + fwidth = prec = 0; + zerofill = 0; + leftjust = 0; + plussign = 0; + prefix = 0; + ldspace = 0; + modifier[0] = '\0'; + + if ('%'==fmt[0] && '%'==fmt[1]) { + HDputc ('%', stream); + fmt += 2; + nout++; + } else if ('%'==fmt[0]) { + s = fmt + 1; + + /* Flags */ + while(HDstrchr ("-+ #", *s)) { + switch(*s) { case '-': leftjust = 1; break; @@ -155,244 +155,251 @@ HDfprintf(FILE *stream, const char *fmt, ...) case '#': prefix = 1; break; - } /* end switch */ /*lint !e744 Switch statement doesn't _need_ default */ - s++; - } /* end while */ - - /* Field width */ - if (HDisdigit (*s)) { - zerofill = ('0'==*s); - fwidth = (int)HDstrtol (s, &rest, 10); - s = rest; - } else if ('*'==*s) { - fwidth = va_arg (ap, int); - if (fwidth<0) { - leftjust = 1; - fwidth = -fwidth; - } - s++; - } + } /* end switch */ /*lint !e744 Switch statement doesn't _need_ default */ + s++; + } /* end while */ + + /* Field width */ + if(HDisdigit(*s)) { + zerofill = ('0' == *s); + fwidth = (int)HDstrtol (s, &rest, 10); + s = rest; + } /* end if */ + else if ('*'==*s) { + fwidth = va_arg (ap, int); + if(fwidth < 0) { + leftjust = 1; + fwidth = -fwidth; + } + s++; + } + + /* Precision */ + if('.'==*s) { + s++; + if(HDisdigit(*s)) { + prec = (int)HDstrtol(s, &rest, 10); + s = rest; + } else if('*'==*s) { + prec = va_arg(ap, int); + s++; + } + if(prec < 1) + prec = 1; + } + + /* Extra type modifiers */ + if(HDstrchr("ZHhlqLI", *s)) { + switch(*s) { + /*lint --e{506} Don't issue warnings about constant value booleans */ + /*lint --e{774} Don't issue warnings boolean within 'if' always evaluates false/true */ + case 'H': + if(sizeof(hsize_t) < sizeof(long)) + modifier[0] = '\0'; + else if(sizeof(hsize_t) == sizeof(long)) + HDstrncpy(modifier, "l", 2); + else + HDstrncpy(modifier, H5_PRINTF_LL_WIDTH, HDstrlen(H5_PRINTF_LL_WIDTH) + 1); + break; - /* Precision */ - if ('.'==*s) { - s++; - if (HDisdigit (*s)) { - prec = (int)HDstrtol (s, &rest, 10); - s = rest; - } else if ('*'==*s) { - prec = va_arg (ap, int); - s++; - } - if (prec<1) prec = 1; - } + case 'Z': + if(sizeof(size_t) < sizeof(long)) + modifier[0] = '\0'; + else if(sizeof(size_t) == sizeof(long)) + HDstrncpy(modifier, "l", 2); + else + HDstrncpy(modifier, H5_PRINTF_LL_WIDTH, HDstrlen(H5_PRINTF_LL_WIDTH) + 1); + break; - /* Extra type modifiers */ - if (HDstrchr ("ZHhlqLI", *s)) { - switch (*s) { - /*lint --e{506} Don't issue warnings about constant value booleans */ - /*lint --e{774} Don't issue warnings boolean within 'if' always evaluates false/true */ - case 'H': - if (sizeof(hsize_t)<sizeof(long)) { - modifier[0] = '\0'; - } else if (sizeof(hsize_t)==sizeof(long)) { - HDstrcpy (modifier, "l"); - } else { - HDstrcpy (modifier, H5_PRINTF_LL_WIDTH); - } - break; - case 'Z': - if (sizeof(size_t)<sizeof(long)) { - modifier[0] = '\0'; - } else if (sizeof(size_t)==sizeof(long)) { - HDstrcpy (modifier, "l"); - } else { - HDstrcpy (modifier, H5_PRINTF_LL_WIDTH); - } - break; - default: - /* Handle 'I64' modifier for Microsoft's "__int64" type */ - if(*s=='I' && *(s+1)=='6' && *(s+2)=='4') { - modifier[0] = *s; - modifier[1] = *(s+1); - modifier[2] = *(s+2); - modifier[3] = '\0'; - s+=2; /* Increment over 'I6', the '4' is taken care of below */ - } /* end if */ - else { - /* Handle 'll' for long long types */ - if(*s=='l' && *(s+1)=='l') { + default: + /* Handle 'I64' modifier for Microsoft's "__int64" type */ + if(*s=='I' && *(s+1)=='6' && *(s+2)=='4') { modifier[0] = *s; - modifier[1] = *s; - modifier[2] = '\0'; - s++; /* Increment over first 'l', second is taken care of below */ + modifier[1] = *(s+1); + modifier[2] = *(s+2); + modifier[3] = '\0'; + s += 2; /* Increment over 'I6', the '4' is taken care of below */ } /* end if */ else { - modifier[0] = *s; - modifier[1] = '\0'; + /* Handle 'll' for long long types */ + if(*s=='l' && *(s+1)=='l') { + modifier[0] = *s; + modifier[1] = *s; + modifier[2] = '\0'; + s++; /* Increment over first 'l', second is taken care of below */ + } /* end if */ + else { + modifier[0] = *s; + modifier[1] = '\0'; + } /* end else */ } /* end else */ - } /* end else */ - break; - } - s++; - } - - /* Conversion */ - conv = *s++; - - /* Create the format template */ - sprintf (format_templ, "%%%s%s%s%s%s", - leftjust?"-":"", plussign?"+":"", - ldspace?" ":"", prefix?"#":"", zerofill?"0":""); - if (fwidth>0) - sprintf (format_templ+HDstrlen(format_templ), "%d", fwidth); - if (prec>0) - sprintf (format_templ+HDstrlen(format_templ), ".%d", prec); - if (*modifier) - sprintf (format_templ+HDstrlen(format_templ), "%s", modifier); - sprintf (format_templ+HDstrlen(format_templ), "%c", conv); - - - /* Conversion */ - switch (conv) { - case 'd': - case 'i': - if (!HDstrcmp(modifier, "h")) { - short x = (short)va_arg (ap, int); - n = fprintf (stream, format_templ, x); - } else if (!*modifier) { - int x = va_arg (ap, int); - n = fprintf (stream, format_templ, x); - } else if (!HDstrcmp (modifier, "l")) { - long x = va_arg (ap, long); - n = fprintf (stream, format_templ, x); - } else { - int64_t x = va_arg(ap, int64_t); - n = fprintf (stream, format_templ, x); - } - break; - - case 'o': - case 'u': - case 'x': - case 'X': - if (!HDstrcmp (modifier, "h")) { - unsigned short x = (unsigned short)va_arg (ap, unsigned int); - n = fprintf (stream, format_templ, x); - } else if (!*modifier) { - unsigned int x = va_arg (ap, unsigned int); /*lint !e732 Loss of sign not really occuring */ - n = fprintf (stream, format_templ, x); - } else if (!HDstrcmp (modifier, "l")) { - unsigned long x = va_arg (ap, unsigned long); /*lint !e732 Loss of sign not really occuring */ - n = fprintf (stream, format_templ, x); - } else { - uint64_t x = va_arg(ap, uint64_t); /*lint !e732 Loss of sign not really occuring */ - n = fprintf (stream, format_templ, x); - } - break; - - case 'f': - case 'e': - case 'E': - case 'g': - case 'G': - if (!HDstrcmp (modifier, "h")) { - float x = (float) va_arg (ap, double); - n = fprintf (stream, format_templ, x); - } else if (!*modifier || !HDstrcmp (modifier, "l")) { - double x = va_arg (ap, double); - n = fprintf (stream, format_templ, x); - } else { - /* - * Some compilers complain when `long double' and - * `double' are the same thing. - */ + break; + } + s++; + } + + /* Conversion */ + conv = *s++; + + /* Create the format template */ + sprintf(format_templ, "%%%s%s%s%s%s", (leftjust ? "-" : ""), + (plussign ? "+" : ""), (ldspace ? " " : ""), + (prefix ? "#" : ""), (zerofill ? "0" : "")); + if(fwidth > 0) + sprintf(format_templ+HDstrlen(format_templ), "%d", fwidth); + if(prec > 0) + sprintf(format_templ+HDstrlen(format_templ), ".%d", prec); + if(*modifier) + sprintf(format_templ+HDstrlen(format_templ), "%s", modifier); + sprintf (format_templ+HDstrlen(format_templ), "%c", conv); + + + /* Conversion */ + switch (conv) { + case 'd': + case 'i': + if(!HDstrcmp(modifier, "h")) { + short x = (short)va_arg (ap, int); + n = fprintf (stream, format_templ, x); + } else if(!*modifier) { + int x = va_arg (ap, int); + n = fprintf (stream, format_templ, x); + } else if(!HDstrcmp (modifier, "l")) { + long x = va_arg (ap, long); + n = fprintf (stream, format_templ, x); + } else { + int64_t x = va_arg(ap, int64_t); + n = fprintf (stream, format_templ, x); + } + break; + + case 'o': + case 'u': + case 'x': + case 'X': + if(!HDstrcmp(modifier, "h")) { + unsigned short x = (unsigned short)va_arg (ap, unsigned int); + n = fprintf(stream, format_templ, x); + } else if(!*modifier) { + unsigned int x = va_arg (ap, unsigned int); /*lint !e732 Loss of sign not really occuring */ + n = fprintf(stream, format_templ, x); + } else if(!HDstrcmp(modifier, "l")) { + unsigned long x = va_arg (ap, unsigned long); /*lint !e732 Loss of sign not really occuring */ + n = fprintf(stream, format_templ, x); + } else { + uint64_t x = va_arg(ap, uint64_t); /*lint !e732 Loss of sign not really occuring */ + n = fprintf(stream, format_templ, x); + } + break; + + case 'f': + case 'e': + case 'E': + case 'g': + case 'G': + if(!HDstrcmp(modifier, "h")) { + float x = (float)va_arg(ap, double); + n = fprintf(stream, format_templ, x); + } else if(!*modifier || !HDstrcmp(modifier, "l")) { + double x = va_arg(ap, double); + n = fprintf(stream, format_templ, x); + } else { + /* + * Some compilers complain when `long double' and + * `double' are the same thing. + */ #if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE - long double x = va_arg (ap, long double); - n = fprintf (stream, format_templ, x); + long double x = va_arg(ap, long double); + n = fprintf(stream, format_templ, x); #else - double x = va_arg (ap, double); - n = fprintf (stream, format_templ, x); + double x = va_arg(ap, double); + n = fprintf(stream, format_templ, x); #endif - } - break; - - case 'a': - { - haddr_t x = va_arg (ap, haddr_t); /*lint !e732 Loss of sign not really occuring */ - if (H5F_addr_defined(x)) { - sprintf(format_templ, "%%%s%s%s%s%s", - leftjust?"-":"", plussign?"+":"", - ldspace?" ":"", prefix?"#":"", - zerofill?"0":""); - if (fwidth>0) - sprintf(format_templ+HDstrlen(format_templ), "%d", fwidth); - - /*lint --e{506} Don't issue warnings about constant value booleans */ - /*lint --e{774} Don't issue warnings boolean within 'if' always evaluates false/true */ - if (sizeof(x)==H5_SIZEOF_INT) { - HDstrcat(format_templ, "u"); - } else if (sizeof(x)==H5_SIZEOF_LONG) { - HDstrcat(format_templ, "lu"); - } else if (sizeof(x)==H5_SIZEOF_LONG_LONG) { - HDstrcat(format_templ, H5_PRINTF_LL_WIDTH); - HDstrcat(format_templ, "u"); - } - n = fprintf(stream, format_templ, x); + } + break; + + case 'a': + { + haddr_t x = va_arg (ap, haddr_t); /*lint !e732 Loss of sign not really occuring */ + + if(H5F_addr_defined(x)) { + sprintf(format_templ, "%%%s%s%s%s%s", + (leftjust ? "-" : ""), (plussign ? "+" : ""), + (ldspace ? " " : ""), (prefix ? "#" : ""), + (zerofill ? "0" : "")); + if(fwidth > 0) + sprintf(format_templ + HDstrlen(format_templ), "%d", fwidth); + + /*lint --e{506} Don't issue warnings about constant value booleans */ + /*lint --e{774} Don't issue warnings boolean within 'if' always evaluates false/true */ + if(sizeof(x) == H5_SIZEOF_INT) + HDstrcat(format_templ, "u"); + else if(sizeof(x) == H5_SIZEOF_LONG) + HDstrcat(format_templ, "lu"); + else if(sizeof(x) == H5_SIZEOF_LONG_LONG) { + HDstrcat(format_templ, H5_PRINTF_LL_WIDTH); + HDstrcat(format_templ, "u"); + } + n = fprintf(stream, format_templ, x); + } else { + HDstrcpy(format_templ, "%"); + if(leftjust) + HDstrcat(format_templ, "-"); + if(fwidth) + sprintf(format_templ+HDstrlen(format_templ), "%d", fwidth); + HDstrcat(format_templ, "s"); + fprintf(stream, format_templ, "UNDEF"); + } + } + break; + + case 'c': + { + char x = (char)va_arg(ap, int); + n = fprintf(stream, format_templ, x); + } + break; + + case 's': + case 'p': + { + char *x = va_arg(ap, char*); /*lint !e64 Type mismatch not really occuring */ + n = fprintf(stream, format_templ, x); + } + break; + + case 'n': + format_templ[HDstrlen(format_templ) - 1] = 'u'; + n = fprintf(stream, format_templ, nout); + break; + + case 't': + { + htri_t tri_var = va_arg(ap, htri_t); + + if(tri_var > 0) + fprintf (stream, "TRUE"); + else if(!tri_var) + fprintf(stream, "FALSE"); + else + fprintf(stream, "FAIL(%d)", (int)tri_var); + } + break; + + default: + HDfputs(format_templ, stream); + n = (int)HDstrlen(format_templ); + break; + } + nout += n; + fmt = s; } else { - HDstrcpy(format_templ, "%"); - if (leftjust) - HDstrcat(format_templ, "-"); - if (fwidth) - sprintf(format_templ+HDstrlen(format_templ), "%d", fwidth); - HDstrcat(format_templ, "s"); - fprintf(stream, format_templ, "UNDEF"); + HDputc(*fmt, stream); + fmt++; + nout++; } } - break; - - case 'c': - { - char x = (char)va_arg (ap, int); - n = fprintf (stream, format_templ, x); - } - break; - - case 's': - case 'p': - { - char *x = va_arg (ap, char*); /*lint !e64 Type mismatch not really occuring */ - n = fprintf (stream, format_templ, x); - } - break; - - case 'n': - format_templ[HDstrlen(format_templ)-1] = 'u'; - n = fprintf (stream, format_templ, nout); - break; - - case 't': - { - htri_t tri_var = va_arg (ap, htri_t); - if (tri_var > 0) fprintf (stream, "TRUE"); - else if (!tri_var) fprintf (stream, "FALSE"); - else fprintf (stream, "FAIL(%d)", (int)tri_var); - } - break; - - default: - HDfputs (format_templ, stream); - n = (int)HDstrlen (format_templ); - break; - } - nout += n; - fmt = s; - } else { - HDputc (*fmt, stream); - fmt++; - nout++; - } - } - va_end (ap); + va_end(ap); return nout; } /* end HDfprintf() */ @@ -700,7 +707,7 @@ H5_build_extpath(const char *name, char **extpath/*out*/) * OpenVMS: <disk name>$<partition>:[path]<file name> * i.g. SYS$SYSUSERS:[LU.HDF5.SRC]H5system.c */ - if(CHECK_ABSOLUTE(name)) { + if(H5_CHECK_ABSOLUTE(name)) { if(NULL == (full_path = (char *)H5MM_strdup(name))) HGOTO_ERROR(H5E_INTERNAL, H5E_NOSPACE, FAIL, "memory allocation failed") } /* end if */ @@ -713,24 +720,24 @@ H5_build_extpath(const char *name, char **extpath/*out*/) if(NULL == (new_name = (char *)H5MM_strdup(name))) HGOTO_ERROR(H5E_INTERNAL, H5E_NOSPACE, FAIL, "memory allocation failed") - /* - * Windows: name[0-1] is "<drive-letter>:" - * Get current working directory on the drive specified in NAME - * Unix: does not apply + /* + * Windows: name[0-1] is "<drive-letter>:" + * Get current working directory on the drive specified in NAME + * Unix: does not apply * OpenVMS: does not apply - */ - if(CHECK_ABS_DRIVE(name)) { + */ + if(H5_CHECK_ABS_DRIVE(name)) { drive = name[0] - 'A' + 1; retcwd = HDgetdcwd(drive, cwdpath, MAX_PATH_LEN); HDstrcpy(new_name, &name[2]); } /* end if */ - /* - * Windows: name[0] is a '/' or '\' - * Get current drive - * Unix: does not apply - * OpenVMS: does not apply - */ - else if(CHECK_ABS_PATH(name) && (0 != (drive = HDgetdrive()))) { + /* + * Windows: name[0] is a '/' or '\' + * Get current drive + * Unix: does not apply + * OpenVMS: does not apply + */ + else if(H5_CHECK_ABS_PATH(name) && (0 != (drive = HDgetdrive()))) { sprintf(cwdpath, "%c:%c", (drive+'A'-1), name[0]); retcwd = cwdpath; HDstrcpy(new_name, &name[1]); @@ -749,7 +756,7 @@ H5_build_extpath(const char *name, char **extpath/*out*/) if(NULL == (full_path = (char *)H5MM_malloc(path_len))) HGOTO_ERROR(H5E_INTERNAL, H5E_NOSPACE, FAIL, "memory allocation failed") - HDstrcpy(full_path, cwdpath); + HDstrncpy(full_path, cwdpath, cwdlen + 1); #ifdef H5_VMS /* If the file name contains relative path, cut off the beginning bracket. Also cut off the * ending bracket of CWDPATH to combine the full path name. i.g. @@ -759,15 +766,16 @@ H5_build_extpath(const char *name, char **extpath/*out*/) */ if(new_name[0] == '[') { char *tmp = new_name; + full_path[cwdlen - 1] = '\0'; HDstrcat(full_path, ++tmp); } /* end if */ else - HDstrcat(full_path, new_name); + HDstrncat(full_path, new_name, HDstrlen(new_name)); #else - if(!CHECK_DELIMITER(cwdpath[cwdlen - 1])) - HDstrcat(full_path, DIR_SEPS); - HDstrcat(full_path, new_name); + if(!H5_CHECK_DELIMITER(cwdpath[cwdlen - 1])) + HDstrncat(full_path, H5_DIR_SEPS, HDstrlen(H5_DIR_SEPS)); + HDstrncat(full_path, new_name, HDstrlen(new_name)); #endif } /* end if */ } /* end else */ @@ -776,7 +784,7 @@ H5_build_extpath(const char *name, char **extpath/*out*/) if(full_path) { char *ptr = NULL; - GET_LAST_DELIMITER(full_path, ptr) + H5_GET_LAST_DELIMITER(full_path, ptr) HDassert(ptr); *++ptr = '\0'; *extpath = full_path; diff --git a/src/Makefile.in b/src/Makefile.in index 1393026..db1d143 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -327,6 +327,7 @@ H5_VERSION = @H5_VERSION@ HADDR_T = @HADDR_T@ HAVE_DMALLOC = @HAVE_DMALLOC@ HAVE_FORTRAN_2003 = @HAVE_FORTRAN_2003@ +HAVE_PTHREAD = @HAVE_PTHREAD@ HDF5_HL = @HDF5_HL@ HDF5_INTERFACES = @HDF5_INTERFACES@ HDF_CXX = @HDF_CXX@ @@ -378,7 +379,6 @@ PACKAGE_VERSION = @PACKAGE_VERSION@ PARALLEL = @PARALLEL@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ -PTHREAD = @PTHREAD@ RANLIB = @RANLIB@ ROOT = @ROOT@ RUNPARALLEL = @RUNPARALLEL@ @@ -525,7 +525,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog # Add libtool shared library version numbers to the HDF5 library # See libtool versioning documentation online. LT_VERS_INTERFACE = 6 -LT_VERS_REVISION = 127 +LT_VERS_REVISION = 138 LT_VERS_AGE = 0 H5detect_CFLAGS = -g $(AM_CFLAGS) |