summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt10
-rw-r--r--config/cmake/ConfigureChecks.cmake3
-rw-r--r--config/cmake/H5pubconf.h.in7
-rw-r--r--src/H5FDlog.c627
-rw-r--r--src/H5FDsec2.c605
-rw-r--r--src/H5FDwindows.c1053
-rw-r--r--src/H5FDwindows.h11
7 files changed, 734 insertions, 1582 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 17e655c..ff63012 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -256,16 +256,6 @@ IF (WIN32 AND NOT CYGWIN)
ENDIF (WIN32 AND NOT CYGWIN)
#-----------------------------------------------------------------------------
-# Option to enable use of stdio instead of posix io
-#-----------------------------------------------------------------------------
-IF (WIN32)
- OPTION (HDF5_ENABLE_WINDOWS_STDIO "Enable use of stdio instead of posix io" OFF)
- IF (HDF5_ENABLE_WINDOWS_STDIO)
- SET (H5_WINDOWS_USE_STDIO 1)
- ENDIF (HDF5_ENABLE_WINDOWS_STDIO)
-ENDIF (WIN32)
-
-#-----------------------------------------------------------------------------
# Option to Build Shared/Static libs, default is static
#-----------------------------------------------------------------------------
OPTION (BUILD_SHARED_LIBS "Build Shared Libraries" OFF)
diff --git a/config/cmake/ConfigureChecks.cmake b/config/cmake/ConfigureChecks.cmake
index 87d68c9..733e1a6 100644
--- a/config/cmake/ConfigureChecks.cmake
+++ b/config/cmake/ConfigureChecks.cmake
@@ -156,9 +156,8 @@ IF (WINDOWS)
# Set the flag to indicate that the machine has window style pathname,
# that is, "drive-letter:\" (e.g. "C:") or "drive-letter:/" (e.g. "C:/").
# (This flag should be _unset_ for all machines, except for Windows)
- #
+ #
SET (H5_HAVE_WINDOW_PATH 1)
- SET (WINDOWS_MAX_BUF (1024 * 1024 * 1024))
SET (LINK_LIBS ${LINK_LIBS} "kernel32")
ENDIF (WINDOWS)
SET (H5_DEFAULT_VFD H5FD_SEC2)
diff --git a/config/cmake/H5pubconf.h.in b/config/cmake/H5pubconf.h.in
index 935a1ac..70c6e50 100644
--- a/config/cmake/H5pubconf.h.in
+++ b/config/cmake/H5pubconf.h.in
@@ -12,13 +12,6 @@
/* Define if using a Windows compiler (i.e. Visual Studio) */
#cmakedefine H5_HAVE_VISUAL_STUDIO @H5_HAVE_VISUAL_STUDIO@
-/* Define if the Windows virtual file driver should use buffered IO functions */
-/* #undef WINDOWS_USE_STDIO */
-
-/* Define the maximum write size for the Windows file driver. Larger writes
- will be split into many writes. Safe values are 1 <= WINDOWS_MAX_BUF <= 2GB-1. */
-#cmakedefine WINDOWS_MAX_BUF (1024 * 1024 * 1024)
-
/* Defined if HDF5 was built with CMake AND build as a shared library */
#cmakedefine H5_BUILT_AS_DYNAMIC_LIB @H5_BUILT_AS_DYNAMIC_LIB@
diff --git a/src/H5FDlog.c b/src/H5FDlog.c
index 1f28d0a..3c8b532 100644
--- a/src/H5FDlog.c
+++ b/src/H5FDlog.c
@@ -17,17 +17,17 @@
* Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
* 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).
+ * 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
+#define H5_INTERFACE_INIT_FUNC H5FD_log_init_interface
#include "H5private.h" /* Generic Functions */
@@ -43,9 +43,24 @@
/* 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 */
+ char *logfile; /* Allocated log file name */
unsigned long long flags; /* Flags for logging behavior */
size_t buf_size; /* Size of buffers for track flavor and number of times each byte is accessed */
} H5FD_log_fapl_t;
@@ -65,11 +80,10 @@ static const char *flavors[]={
"H5FD_MEM_OHDR",
};
-/*
- * 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 Unix file). The `pos'
- * value is used to eliminate file position updates when they would be a
+ * 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
* 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
@@ -78,98 +92,100 @@ static const char *flavors[]={
* occurs), and `op' will be set to H5F_OP_UNKNOWN.
*/
typedef struct H5FD_log_t {
- H5FD_t pub; /*public stuff, must be first */
- int fd; /*the unix file */
- haddr_t eoa; /*end of allocated region */
- haddr_t eof; /*end of file; current file size*/
- haddr_t pos; /*current file I/O position */
- H5FD_file_op_t op; /*last operation */
- char filename[H5FD_MAX_FILENAME_LEN]; /* Copy of file name from open operation */
+ H5FD_t pub; /* public stuff, must be first */
+ int fd; /* the unix file */
+ haddr_t eoa; /* end of allocated region */
+ haddr_t eof; /* end of file; current file size */
+ haddr_t pos; /* current file I/O position */
+ H5FD_file_op_t op; /* last operation */
+ char filename[H5FD_MAX_FILENAME_LEN]; /* Copy of file name from open operation */
#ifndef H5_HAVE_WIN32_API
- /*
- * On most systems the combination of device and i-node number uniquely
- * identify a file.
+ /* On most systems the combination of device and i-node number uniquely
+ * identify a file. Note that Cygwin, MinGW and other Windows POSIX
+ * environments have the stat function (which fakes inodes)
+ * and will use the 'device + inodes' scheme as opposed to the
+ * Windows code further below.
*/
- dev_t device; /*file device number */
+ dev_t device; /* file device number */
#ifdef H5_VMS
- ino_t inode[3]; /*file i-node number */
+ ino_t inode[3]; /* file i-node number */
#else
- ino_t inode; /*file i-node number */
+ ino_t inode; /* file i-node number */
#endif /*H5_VMS*/
#else
- /*
- * On H5_HAVE_WIN32_API the low-order word of a unique identifier associated with the
- * file and the volume serial number uniquely identify a file. This number
- * (which, both? -rpm) may change when the system is restarted or when the
- * file is opened. After a process opens a file, the identifier is
- * constant until the file is closed. An application can use this
- * identifier and the volume serial number to determine whether two
- * handles refer to the same file.
+ /* Files in windows are uniquely identified by the volume serial
+ * number and the file index (both low and high parts).
+ *
+ * There are caveats where these numbers can change, especially
+ * on FAT file systems. On NTFS, however, a file should keep
+ * those numbers the same until renamed or deleted (though you
+ * can use ReplaceFile() on NTFS to keep the numbers the same
+ * while renaming).
+ *
+ * See the MSDN "BY_HANDLE_FILE_INFORMATION Structure" entry for
+ * more information.
+ *
+ * http://msdn.microsoft.com/en-us/library/aa363788(v=VS.85).aspx
*/
- DWORD fileindexlo;
- DWORD fileindexhi;
-#endif
+ DWORD nFileIndexLow;
+ DWORD nFileIndexHigh;
+ DWORD dwVolumeSerialNumber;
+
+ HANDLE hFile; /* Native windows file handle */
+#endif /* H5_HAVE_WIN32_API */
- /* Information from properties set by 'h5repart' tool */
- hbool_t fam_to_sec2; /* Whether to eliminate the family driver info
- * and convert this file to a single file */
+ /* Information from properties set by 'h5repart' tool
+ *
+ * Whether to eliminate the family driver info and convert this file to
+ * a single file
+ */
+ hbool_t fam_to_sec2;
/* Fields for tracking I/O operations */
- unsigned char *nread; /* Number of reads from a file location */
- unsigned char *nwrite; /* Number of write to a file location */
- unsigned char *flavor; /* Flavor of information written to file location */
- unsigned long long total_read_ops; /* Total number of read operations */
- unsigned long long total_write_ops; /* Total number of write operations */
- unsigned long long total_seek_ops; /* Total number of seek operations */
- unsigned long long total_truncate_ops; /* Total number of truncate operations */
- double total_read_time; /* Total time spent in read operations */
- double total_write_time; /* Total time spent in write operations */
- double total_seek_time; /* Total time spent in seek operations */
- size_t iosize; /* Size of I/O information buffers */
- FILE *logfp; /* Log file pointer */
- H5FD_log_fapl_t fa; /* Driver-specific file access properties*/
+ unsigned char *nread; /* Number of reads from a file location */
+ unsigned char *nwrite; /* Number of write to a file location */
+ unsigned char *flavor; /* Flavor of information written to file location */
+ unsigned long long total_read_ops; /* Total number of read operations */
+ unsigned long long total_write_ops; /* Total number of write operations */
+ unsigned long long total_seek_ops; /* Total number of seek operations */
+ unsigned long long total_truncate_ops; /* Total number of truncate operations */
+ double total_read_time; /* Total time spent in read operations */
+ double total_write_time; /* Total time spent in write operations */
+ double total_seek_time; /* Total time spent in seek operations */
+ size_t iosize; /* Size of I/O information buffers */
+ FILE *logfp; /* Log file pointer */
+ H5FD_log_fapl_t fa; /* Driver-specific file access properties */
} H5FD_log_t;
-
-/*
- * This driver supports systems that have the lseek64() function by defining
- * some macros here so we don't have to have conditional compilations later
- * throughout the code.
- *
- * HDoff_t: The datatype for file offsets, the second argument of
- * the lseek() or lseek64() call.
- *
- */
-
/*
* 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 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);
@@ -179,43 +195,43 @@ 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 = {
- "log", /*name */
- MAXADDR, /*maxaddr */
- H5F_CLOSE_WEAK, /* fc_degree */
- NULL, /*sb_size */
- NULL, /*sb_encode */
- NULL, /*sb_decode */
- sizeof(H5FD_log_fapl_t), /*fapl_size */
- H5FD_log_fapl_get, /*fapl_get */
- H5FD_log_fapl_copy, /*fapl_copy */
- H5FD_log_fapl_free, /*fapl_free */
- 0, /*dxpl_size */
- NULL, /*dxpl_copy */
- NULL, /*dxpl_free */
- H5FD_log_open, /*open */
- H5FD_log_close, /*close */
- H5FD_log_cmp, /*cmp */
- H5FD_log_query, /*query */
- NULL, /*get_type_map */
- H5FD_log_alloc, /*alloc */
- NULL, /*free */
- H5FD_log_get_eoa, /*get_eoa */
- H5FD_log_set_eoa, /*set_eoa */
- H5FD_log_get_eof, /*get_eof */
+ "log", /*name */
+ MAXADDR, /*maxaddr */
+ H5F_CLOSE_WEAK, /* fc_degree */
+ NULL, /*sb_size */
+ NULL, /*sb_encode */
+ NULL, /*sb_decode */
+ sizeof(H5FD_log_fapl_t), /*fapl_size */
+ H5FD_log_fapl_get, /*fapl_get */
+ H5FD_log_fapl_copy, /*fapl_copy */
+ H5FD_log_fapl_free, /*fapl_free */
+ 0, /*dxpl_size */
+ NULL, /*dxpl_copy */
+ NULL, /*dxpl_free */
+ H5FD_log_open, /*open */
+ H5FD_log_close, /*close */
+ H5FD_log_cmp, /*cmp */
+ H5FD_log_query, /*query */
+ NULL, /*get_type_map */
+ H5FD_log_alloc, /*alloc */
+ NULL, /*free */
+ H5FD_log_get_eoa, /*get_eoa */
+ H5FD_log_set_eoa, /*set_eoa */
+ H5FD_log_get_eof, /*get_eof */
H5FD_log_get_handle, /*get_handle */
- H5FD_log_read, /*read */
- H5FD_log_write, /*write */
- NULL, /*flush */
- H5FD_log_truncate, /*truncate */
+ H5FD_log_read, /*read */
+ H5FD_log_write, /*write */
+ NULL, /*flush */
+ H5FD_log_truncate, /*truncate */
NULL, /*lock */
NULL, /*unlock */
- H5FD_FLMAP_SINGLE /*fl_map */
+ H5FD_FLMAP_SINGLE /*fl_map */
};
/* Declare a free list to manage the H5FD_log_t struct */
@@ -245,15 +261,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
*
*-------------------------------------------------------------------------
@@ -277,11 +293,11 @@ done:
/*---------------------------------------------------------------------------
- * Function: H5FD_log_term
+ * Function: H5FD_log_term
*
- * Purpose: Shut down the VFD
+ * Purpose: Shut down the VFD
*
- * Return: <none>
+ * Returns: <none>
*
* Programmer: Quincey Koziol
* Friday, Jan 30, 2004
@@ -301,25 +317,24 @@ 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. There are no driver
- * specific properties.
+ * 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: Non-negative on success/Negative on failure
*
- * Programmer: Robb Matzke
- * Thursday, February 19, 1998
+ * Programmer: Robb Matzke
+ * Thursday, February 19, 1998
*
*-------------------------------------------------------------------------
*/
herr_t
H5Pset_fapl_log(hid_t fapl_id, const char *logfile, unsigned long long flags, size_t buf_size)
{
- H5FD_log_fapl_t fa; /* File access property list information */
- H5P_genplist_t *plist; /* Property list pointer */
- herr_t ret_value;
+ H5FD_log_fapl_t fa; /* File access property list information */
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value; /* Return value */
FUNC_ENTER_API(H5Pset_fapl_log, FAIL)
H5TRACE4("e", "i*sULz", fapl_id, logfile, flags, buf_size);
@@ -330,7 +345,7 @@ H5Pset_fapl_log(hid_t fapl_id, const char *logfile, unsigned long long flags, si
/* Deep copy the log filename */
fa.logfile = H5MM_xstrdup(logfile);
-
+
fa.flags = flags;
fa.buf_size = buf_size;
ret_value = H5P_set_driver(plist, H5FD_LOG, &fa);
@@ -341,17 +356,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
*
*-------------------------------------------------------------------------
@@ -359,7 +374,7 @@ done:
static void *
H5FD_log_fapl_get(H5FD_t *_file)
{
- H5FD_log_t *file = (H5FD_log_t *)_file;
+ H5FD_log_t *file = (H5FD_log_t *)_file;
void *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_log_fapl_get)
@@ -372,14 +387,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
*
*-------------------------------------------------------------------------
@@ -423,14 +438,14 @@ 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: Success: 0
+ * Failure: -1
*
- * Programmer: Quincey Koziol
+ * Programmer: Quincey Koziol
* Thursday, April 20, 2000
*
*-------------------------------------------------------------------------
@@ -438,7 +453,7 @@ done:
static herr_t
H5FD_log_fapl_free(void *_fa)
{
- H5FD_log_fapl_t *fa = (H5FD_log_fapl_t*)_fa;
+ H5FD_log_fapl_t *fa = (H5FD_log_fapl_t*)_fa;
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_log_fapl_free)
@@ -452,16 +467,16 @@ H5FD_log_fapl_free(void *_fa)
/*-------------------------------------------------------------------------
- * Function: H5FD_log_open
+ * Function: H5FD_log_open
*
- * Purpose: Create and/or opens a Unix 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
*
*-------------------------------------------------------------------------
@@ -469,13 +484,12 @@ 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;
+ 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_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
- HFILE filehandle;
struct _BY_HANDLE_FILE_INFORMATION fileinfo;
#endif
#ifdef H5_HAVE_GETTIMEOFDAY
@@ -483,8 +497,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(H5FD_log_open)
@@ -572,10 +586,16 @@ H5FD_log_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
file->pos = HADDR_UNDEF;
file->op = OP_UNKNOWN;
#ifdef H5_HAVE_WIN32_API
- filehandle = _get_osfhandle(fd);
- (void)GetFileInformationByHandle((HANDLE)filehandle, &fileinfo);
- file->fileindexhi = fileinfo.nFileIndexHigh;
- file->fileindexlo = fileinfo.nFileIndexLow;
+ file->hFile = (HANDLE)_get_osfhandle(fd);
+ if(INVALID_HANDLE_VALUE == file->hFile)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to get Windows file handle")
+
+ if(!GetFileInformationByHandle((HANDLE)file->hFile, &fileinfo))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to get Windows file information")
+
+ file->nFileIndexHigh = fileinfo.nFileIndexHigh;
+ file->nFileIndexLow = fileinfo.nFileIndexLow;
+ file->dwVolumeSerialNumber = fileinfo.dwVolumeSerialNumber;
#else /* H5_HAVE_WIN32_API */
file->device = sb.st_dev;
#ifdef H5_VMS
@@ -655,14 +675,14 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5FD_log_close
+ * Function: H5FD_log_close
*
- * Purpose: Closes a Unix file.
+ * Purpose: Closes an HDF5 file.
*
- * Return: Success: 0
- * Failure: -1, file not closed.
+ * Return: Success: 0
+ * Failure: -1, file not closed.
*
- * Programmer: Robb Matzke
+ * Programmer: Robb Matzke
* Thursday, July 29, 1999
*
*-------------------------------------------------------------------------
@@ -670,7 +690,7 @@ done:
static herr_t
H5FD_log_close(H5FD_t *_file)
{
- H5FD_log_t *file = (H5FD_log_t *)_file;
+ H5FD_log_t *file = (H5FD_log_t *)_file;
#ifdef H5_HAVE_GETTIMEOFDAY
struct timeval timeval_start, timeval_stop;
#endif /* H5_HAVE_GETTIMEOFDAY */
@@ -803,16 +823,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
*
*-------------------------------------------------------------------------
@@ -820,19 +840,21 @@ 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_NOFUNC(H5FD_log_cmp)
#ifdef H5_HAVE_WIN32_API
- if(f1->fileindexhi < f2->fileindexhi) HGOTO_DONE(-1)
- if(f1->fileindexhi > f2->fileindexhi) HGOTO_DONE(1)
+ if(f1->dwVolumeSerialNumber < f2->dwVolumeSerialNumber) HGOTO_DONE(-1)
+ if(f1->dwVolumeSerialNumber > f2->dwVolumeSerialNumber) HGOTO_DONE(1)
- if(f1->fileindexlo < f2->fileindexlo) HGOTO_DONE(-1)
- if(f1->fileindexlo > f2->fileindexlo) HGOTO_DONE(1)
+ if(f1->nFileIndexHigh < f2->nFileIndexHigh) HGOTO_DONE(-1)
+ if(f1->nFileIndexHigh > f2->nFileIndexHigh) HGOTO_DONE(1)
+ if(f1->nFileIndexLow < f2->nFileIndexLow) HGOTO_DONE(-1)
+ if(f1->nFileIndexLow > f2->nFileIndexLow) HGOTO_DONE(1)
#else
#ifdef H5_DEV_T_IS_SCALAR
if(f1->device < f2->device) HGOTO_DONE(-1)
@@ -862,15 +884,15 @@ 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: Success: non-negative
+ * Failure: negative
*
- * Programmer: Quincey Koziol
+ * Programmer: Quincey Koziol
* Friday, August 25, 2000
*
*-------------------------------------------------------------------------
@@ -878,7 +900,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_NOFUNC(H5FD_log_query)
@@ -901,14 +923,14 @@ 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
*
*-------------------------------------------------------------------------
@@ -917,7 +939,7 @@ H5FD_log_query(const H5FD_t *_file, unsigned long *flags /* out */)
static haddr_t
H5FD_log_alloc(H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id, hsize_t size)
{
- H5FD_log_t *file = (H5FD_log_t *)_file;
+ H5FD_log_t *file = (H5FD_log_t *)_file;
haddr_t addr;
haddr_t ret_value; /* Return value */
@@ -955,16 +977,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
*
*-------------------------------------------------------------------------
@@ -972,7 +994,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_NOFUNC(H5FD_log_get_eoa)
@@ -981,16 +1003,16 @@ 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: Success: 0
+ * Failure: -1
*
- * Programmer: Robb Matzke
+ * Programmer: Robb Matzke
* Thursday, July 29, 1999
*
*-------------------------------------------------------------------------
@@ -998,7 +1020,7 @@ 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 UNUSED type, haddr_t addr)
{
- H5FD_log_t *file = (H5FD_log_t *)_file;
+ H5FD_log_t *file = (H5FD_log_t *)_file;
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_log_set_eoa)
@@ -1009,18 +1031,18 @@ H5FD_log_set_eoa(H5FD_t *_file, H5FD_mem_t UNUSED 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 Unix 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 Unix 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
*
*-------------------------------------------------------------------------
@@ -1028,7 +1050,7 @@ H5FD_log_set_eoa(H5FD_t *_file, H5FD_mem_t UNUSED type, haddr_t addr)
static haddr_t
H5FD_log_get_eof(const H5FD_t *_file)
{
- const H5FD_log_t *file = (const H5FD_log_t *)_file;
+ const H5FD_log_t *file = (const H5FD_log_t *)_file;
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_log_get_eof)
@@ -1068,17 +1090,17 @@ 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: Zero. Result is stored in caller-supplied
+ * buffer BUF.
+ * Failure: -1, Contents of buffer BUF are undefined.
*
- * Programmer: Robb Matzke
+ * Programmer: Robb Matzke
* Thursday, July 29, 1999
*
*-------------------------------------------------------------------------
@@ -1086,10 +1108,9 @@ done:
/* 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;
- ssize_t nbytes;
+ 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
@@ -1176,10 +1197,23 @@ H5FD_log_read(H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id, haddr_t addr
HDgettimeofday(&timeval_start, NULL);
#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 */
+
+ /* 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;
+ else
+ bytes_in = (h5_log_io_t)size;
+
do {
- nbytes = HDread(file->fd, buf, size);
- } while(-1 == nbytes && EINTR == errno);
- if(-1 == nbytes) { /* error */
+ bytes_read = HDread(file->fd, buf, bytes_in);
+ } while(-1 == bytes_read && EINTR == errno);
+
+ if(-1 == bytes_read) { /* error */
int myerrno = errno;
time_t mytime = HDtime(NULL);
HDoff_t myoffset = HDlseek(file->fd, (HDoff_t)0, SEEK_CUR);
@@ -1189,18 +1223,20 @@ H5FD_log_read(H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id, haddr_t addr
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);
} /* end if */
- if(0 == nbytes) {
+
+ if(0 == bytes_read) {
/* end of file but not end of format address space */
HDmemset(buf, 0, size);
break;
} /* end if */
- HDassert(nbytes >= 0);
- HDassert((size_t)nbytes <= size);
- H5_CHECK_OVERFLOW(nbytes, ssize_t, size_t);
- size -= (size_t)nbytes;
- H5_CHECK_OVERFLOW(nbytes, ssize_t, haddr_t);
- addr += (haddr_t)nbytes;
- buf = (char *)buf + nbytes;
+
+ HDassert(bytes_read >= 0);
+ HDassert((size_t)bytes_read <= size);
+
+ size -= (size_t)bytes_read;
+ addr += (haddr_t)bytes_read;
+ buf = (char *)buf + bytes_read;
+
} /* end while */
#ifdef H5_HAVE_GETTIMEOFDAY
if(file->fa.flags & H5FD_LOG_TIME_READ)
@@ -1256,16 +1292,16 @@ 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: Success: Zero
+ * Failure: -1
*
- * Programmer: Robb Matzke
+ * Programmer: Robb Matzke
* Thursday, July 29, 1999
*
*-------------------------------------------------------------------------
@@ -1273,10 +1309,9 @@ done:
/* 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;
- ssize_t nbytes;
+ 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
@@ -1368,10 +1403,23 @@ H5FD_log_write(H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id, haddr_t add
HDgettimeofday(&timeval_start, NULL);
#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 */
+
+ /* 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;
+ else
+ bytes_in = (h5_log_io_t)size;
+
do {
- nbytes = HDwrite(file->fd, buf, size);
- } while(-1 == nbytes && EINTR == errno);
- if(-1 == nbytes) { /* error */
+ bytes_wrote = HDwrite(file->fd, buf, bytes_in);
+ } while(-1 == bytes_wrote && EINTR == errno);
+
+ if(-1 == bytes_wrote) { /* error */
int myerrno = errno;
time_t mytime = HDtime(NULL);
HDoff_t myoffset = HDlseek(file->fd, (HDoff_t)0, SEEK_CUR);
@@ -1381,13 +1429,13 @@ H5FD_log_write(H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id, haddr_t add
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);
} /* end if */
- HDassert(nbytes > 0);
- HDassert((size_t)nbytes <= size);
- H5_CHECK_OVERFLOW(nbytes, ssize_t, size_t);
- size -= (size_t)nbytes;
- H5_CHECK_OVERFLOW(nbytes, ssize_t, haddr_t);
- addr += (haddr_t)nbytes;
- buf = (const char *)buf + nbytes;
+
+ HDassert(bytes_wrote > 0);
+ HDassert((size_t)bytes_wrote <= size);
+
+ size -= (size_t)bytes_wrote;
+ addr += (haddr_t)bytes_wrote;
+ buf = (const char *)buf + bytes_wrote;
} /* end while */
#ifdef H5_HAVE_GETTIMEOFDAY
if(file->fa.flags & H5FD_LOG_TIME_WRITE)
@@ -1449,15 +1497,15 @@ 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: Success: Non-negative
+ * Failure: Negative
*
- * Programmer: Robb Matzke
+ * Programmer: Robb Matzke
* Wednesday, August 4, 1999
*
*-------------------------------------------------------------------------
@@ -1466,7 +1514,7 @@ done:
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;
+ H5FD_log_t *file = (H5FD_log_t *)_file;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5FD_log_truncate)
@@ -1476,17 +1524,30 @@ H5FD_log_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t UNUSED closing)
/* Extend the file to make sure it's large enough */
if(!H5F_addr_eq(file->eoa, file->eof)) {
#ifdef H5_HAVE_WIN32_API
- HFILE filehandle; /* Windows file handle */
- LARGE_INTEGER li; /* 64-bit integer for SetFilePointer() call */
-
- /* Map the posix file handle to a Windows file handle */
- filehandle = _get_osfhandle(file->fd);
-
- /* Translate 64-bit integers into form Windows wants */
- /* [This algorithm is from the Windows documentation for SetFilePointer()] */
- li.QuadPart = (LONGLONG)file->eoa;
- (void)SetFilePointer((HANDLE)filehandle, li.LowPart, &li.HighPart, FILE_BEGIN);
- if(SetEndOfFile((HANDLE)filehandle) == 0)
+ LARGE_INTEGER li; /* 64-bit (union) integer for SetFilePointer() call */
+ DWORD dwPtrLow; /* Low-order pointer bits from SetFilePointer()
+ * Only used as an error code here.
+ */
+ DWORD dwError; /* DWORD error code from GetLastError() */
+ BOOL bError; /* Boolean error flag */
+
+ /* Windows uses this odd QuadPart union for 32/64-bit portability */
+ li.QuadPart = (__int64)file->eoa;
+
+ /* Extend the file to make sure it's large enough.
+ *
+ * Since INVALID_SET_FILE_POINTER can technically be a valid return value
+ * from SetFilePointer(), we also need to check GetLastError().
+ */
+ dwPtrLow = SetFilePointer(file->hFile, li.LowPart, &li.HighPart, FILE_BEGIN);
+ if(INVALID_SET_FILE_POINTER == dwPtrLow) {
+ dwError = GetLastError();
+ if(dwError != NO_ERROR )
+ HGOTO_ERROR(H5E_FILE, H5E_FILEOPEN, FAIL, "unable to set file pointer")
+ }
+
+ bError = SetEndOfFile(file->hFile);
+ if(0 == bError)
HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")
#else /* H5_HAVE_WIN32_API */
#ifdef H5_VMS
diff --git a/src/H5FDsec2.c b/src/H5FDsec2.c
index 14598d2..a7ae93e 100644
--- a/src/H5FDsec2.c
+++ b/src/H5FDsec2.c
@@ -17,36 +17,50 @@
* 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;
-/*
- * The description of a file belonging to this driver. The `eoa' and `eof'
+/* 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'
* determine the amount of hdf5 address space in use and the high-water mark
- * of the file (the current size of the underlying Unix file). The `pos'
- * value is used to eliminate file position updates when they would be a
+ * 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
* 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
@@ -55,80 +69,82 @@ static hid_t H5FD_SEC2_g = 0;
* occurs), and `op' will be set to H5F_OP_UNKNOWN.
*/
typedef struct H5FD_sec2_t {
- H5FD_t pub; /*public stuff, must be first */
- int fd; /*the unix file */
- haddr_t eoa; /*end of allocated region */
- haddr_t eof; /*end of file; current file size*/
- haddr_t pos; /*current file I/O position */
- H5FD_file_op_t op; /*last operation */
- char filename[H5FD_MAX_FILENAME_LEN]; /* Copy of file name from open operation */
+ H5FD_t pub; /* public stuff, must be first */
+ int fd; /* the filesystem file descriptor */
+ haddr_t eoa; /* end of allocated region */
+ haddr_t eof; /* end of file; current file size */
+ haddr_t pos; /* current file I/O position */
+ H5FD_file_op_t op; /* last operation */
+ char filename[H5FD_MAX_FILENAME_LEN]; /* Copy of file name from open operation */
#ifndef H5_HAVE_WIN32_API
- /*
- * On most systems the combination of device and i-node number uniquely
- * identify a file.
+ /* On most systems the combination of device and i-node number uniquely
+ * identify a file. Note that Cygwin, MinGW and other Windows POSIX
+ * environments have the stat function (which fakes inodes)
+ * and will use the 'device + inodes' scheme as opposed to the
+ * Windows code further below.
*/
- dev_t device; /*file device number */
+ dev_t device; /* file device number */
#ifdef H5_VMS
- ino_t inode[3]; /*file i-node number */
+ ino_t inode[3]; /* file i-node number */
#else
- ino_t inode; /*file i-node number */
-#endif /*H5_VMS*/
+ ino_t inode; /* file i-node number */
+#endif /* H5_VMS */
#else
- /*
- * On H5_HAVE_WIN32_API the low-order word of a unique identifier associated with the
- * file and the volume serial number uniquely identify a file. This number
- * (which, both? -rpm) may change when the system is restarted or when the
- * file is opened. After a process opens a file, the identifier is
- * constant until the file is closed. An application can use this
- * identifier and the volume serial number to determine whether two
- * handles refer to the same file.
+ /* Files in windows are uniquely identified by the volume serial
+ * number and the file index (both low and high parts).
+ *
+ * There are caveats where these numbers can change, especially
+ * on FAT file systems. On NTFS, however, a file should keep
+ * those numbers the same until renamed or deleted (though you
+ * can use ReplaceFile() on NTFS to keep the numbers the same
+ * while renaming).
+ *
+ * See the MSDN "BY_HANDLE_FILE_INFORMATION Structure" entry for
+ * more information.
+ *
+ * http://msdn.microsoft.com/en-us/library/aa363788(v=VS.85).aspx
*/
- DWORD fileindexlo;
- DWORD fileindexhi;
-#endif
-
- /* Information from properties set by 'h5repart' tool */
- hbool_t fam_to_sec2; /* Whether to eliminate the family driver info
- * and convert this file to a single file */
+ DWORD nFileIndexLow;
+ DWORD nFileIndexHigh;
+ DWORD dwVolumeSerialNumber;
+
+ HANDLE hFile; /* Native windows file handle */
+#endif /* H5_HAVE_WIN32_API */
+
+ /* Information from properties set by 'h5repart' tool
+ *
+ * Whether to eliminate the family driver info and convert this file to
+ * a single file.
+ */
+ hbool_t fam_to_sec2;
} H5FD_sec2_t;
-
-/*
- * This driver supports systems that have the lseek64() function by defining
- * some macros here so we don't have to have conditional compilations later
- * throughout the code.
- *
- * HDoff_t: The datatype for file offsets, the second argument of
- * the lseek() or lseek64() call.
- *
- */
-
/*
* 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 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);
@@ -137,43 +153,43 @@ 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 */
- 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 */
+ "sec2", /*name */
+ MAXADDR, /*maxaddr */
+ H5F_CLOSE_WEAK, /* fc_degree */
+ 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 */
+ H5FD_sec2_read, /*read */
+ H5FD_sec2_write, /*write */
+ NULL, /*flush */
+ H5FD_sec2_truncate, /*truncate */
NULL, /*lock */
NULL, /*unlock */
- H5FD_FLMAP_SINGLE /*fl_map */
+ H5FD_FLMAP_SINGLE /*fl_map */
};
/* Declare a free list to manage the H5FD_sec2_t struct */
@@ -203,15 +219,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
*
*-------------------------------------------------------------------------
@@ -235,11 +251,11 @@ done:
/*---------------------------------------------------------------------------
- * Function: H5FD_sec2_term
+ * Function: H5FD_sec2_term
*
- * Purpose: Shut down the VFD
+ * Purpose: Shut down the VFD
*
- * Return: <none>
+ * Returns: <none>
*
* Programmer: Quincey Koziol
* Friday, Jan 30, 2004
@@ -259,16 +275,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: Non-negative on success/Negative on failure
*
- * Programmer: Robb Matzke
- * Thursday, February 19, 1998
+ * Programmer: Robb Matzke
+ * Thursday, February 19, 1998
*
*-------------------------------------------------------------------------
*/
@@ -292,16 +308,16 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5FD_sec2_open
+ * Function: H5FD_sec2_open
*
- * Purpose: Create and/or opens a Unix 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
*
*-------------------------------------------------------------------------
@@ -309,15 +325,14 @@ done:
static H5FD_t *
H5FD_sec2_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
{
- H5FD_sec2_t *file = NULL; /* sec2 VFD info */
- int fd = (-1); /* File descriptor */
- int o_flags; /* Flags for open() call */
+ H5FD_sec2_t *file = NULL; /* sec2 VFD info */
+ int fd = -1; /* File descriptor */
+ int o_flags; /* Flags for open() call */
#ifdef H5_HAVE_WIN32_API
- HFILE filehandle;
struct _BY_HANDLE_FILE_INFORMATION fileinfo;
#endif
- h5_stat_t sb;
- H5FD_t *ret_value; /* Return value */
+ h5_stat_t sb;
+ H5FD_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5FD_sec2_open)
@@ -344,9 +359,9 @@ H5FD_sec2_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
/* Open the file */
if((fd = HDopen(name, o_flags, 0666)) < 0) {
int myerrno = errno;
-
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: name = '%s', errno = %d, error message = '%s', flags = %x, o_flags = %x", name, myerrno, HDstrerror(myerrno), flags, (unsigned)o_flags);
} /* end if */
+
if(HDfstat(fd, &sb) < 0)
HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, "unable to fstat file")
@@ -359,20 +374,25 @@ H5FD_sec2_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
file->pos = HADDR_UNDEF;
file->op = OP_UNKNOWN;
#ifdef H5_HAVE_WIN32_API
- filehandle = _get_osfhandle(fd);
- (void)GetFileInformationByHandle((HANDLE)filehandle, &fileinfo);
- file->fileindexhi = fileinfo.nFileIndexHigh;
- file->fileindexlo = fileinfo.nFileIndexLow;
+ file->hFile = (HANDLE)_get_osfhandle(fd);
+ if(INVALID_HANDLE_VALUE == file->hFile)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to get Windows file handle")
+
+ if(!GetFileInformationByHandle((HANDLE)file->hFile, &fileinfo))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to get Windows file information")
+
+ file->nFileIndexHigh = fileinfo.nFileIndexHigh;
+ file->nFileIndexLow = fileinfo.nFileIndexLow;
+ file->dwVolumeSerialNumber = fileinfo.dwVolumeSerialNumber;
#else /* H5_HAVE_WIN32_API */
file->device = sb.st_dev;
#ifdef H5_VMS
file->inode[0] = sb.st_ino[0];
file->inode[1] = sb.st_ino[1];
file->inode[2] = sb.st_ino[2];
-#else
+#else /* H5_VMS */
file->inode = sb.st_ino;
-#endif /*H5_VMS*/
-
+#endif /* H5_VMS */
#endif /* H5_HAVE_WIN32_API */
/* Retain a copy of the name used to open the file, for possible error reporting */
@@ -413,14 +433,14 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5FD_sec2_close
+ * Function: H5FD_sec2_close
*
- * Purpose: Closes a Unix file.
+ * Purpose: Closes an HDF5 file.
*
- * Return: Success: 0
- * Failure: -1, file not closed.
+ * Return: Success: 0
+ * Failure: -1, file not closed.
*
- * Programmer: Robb Matzke
+ * Programmer: Robb Matzke
* Thursday, July 29, 1999
*
*-------------------------------------------------------------------------
@@ -428,7 +448,7 @@ done:
static herr_t
H5FD_sec2_close(H5FD_t *_file)
{
- H5FD_sec2_t *file = (H5FD_sec2_t *)_file;
+ H5FD_sec2_t *file = (H5FD_sec2_t *)_file;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5FD_sec2_close)
@@ -449,16 +469,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
*
*-------------------------------------------------------------------------
@@ -466,20 +486,22 @@ 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_NOFUNC(H5FD_sec2_cmp)
#ifdef H5_HAVE_WIN32_API
- if(f1->fileindexhi < f2->fileindexhi) HGOTO_DONE(-1)
- if(f1->fileindexhi > f2->fileindexhi) HGOTO_DONE(1)
+ if(f1->dwVolumeSerialNumber < f2->dwVolumeSerialNumber) HGOTO_DONE(-1)
+ if(f1->dwVolumeSerialNumber > f2->dwVolumeSerialNumber) HGOTO_DONE(1)
- if(f1->fileindexlo < f2->fileindexlo) HGOTO_DONE(-1)
- if(f1->fileindexlo > f2->fileindexlo) HGOTO_DONE(1)
+ if(f1->nFileIndexHigh < f2->nFileIndexHigh) HGOTO_DONE(-1)
+ if(f1->nFileIndexHigh > f2->nFileIndexHigh) HGOTO_DONE(1)
-#else
+ if(f1->nFileIndexLow < f2->nFileIndexLow) HGOTO_DONE(-1)
+ if(f1->nFileIndexLow > f2->nFileIndexLow) HGOTO_DONE(1)
+#else /* H5_HAVE_WIN32_API */
#ifdef H5_DEV_T_IS_SCALAR
if(f1->device < f2->device) HGOTO_DONE(-1)
if(f1->device > f2->device) HGOTO_DONE(1)
@@ -491,16 +513,14 @@ H5FD_sec2_cmp(const H5FD_t *_f1, const H5FD_t *_f2)
if(HDmemcmp(&(f1->device),&(f2->device),sizeof(dev_t)) < 0) HGOTO_DONE(-1)
if(HDmemcmp(&(f1->device),&(f2->device),sizeof(dev_t)) > 0) HGOTO_DONE(1)
#endif /* H5_DEV_T_IS_SCALAR */
-
-#ifndef H5_VMS
- if(f1->inode < f2->inode) HGOTO_DONE(-1)
- if(f1->inode > f2->inode) HGOTO_DONE(1)
-#else
+#ifdef H5_VMS
if(HDmemcmp(&(f1->inode), &(f2->inode), 3 * sizeof(ino_t)) < 0) HGOTO_DONE(-1)
if(HDmemcmp(&(f1->inode), &(f2->inode), 3 * sizeof(ino_t)) > 0) HGOTO_DONE(1)
-#endif /*H5_VMS*/
-
-#endif
+#else /* H5_VMS */
+ if(f1->inode < f2->inode) HGOTO_DONE(-1)
+ if(f1->inode > f2->inode) HGOTO_DONE(1)
+#endif /* H5_VMS */
+#endif /* H5_HAVE_WIN32_API */
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -508,15 +528,15 @@ 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: Success: non-negative
+ * Failure: negative
*
- * Programmer: Quincey Koziol
+ * Programmer: Quincey Koziol
* Friday, August 25, 2000
*
*-------------------------------------------------------------------------
@@ -524,18 +544,18 @@ done:
static herr_t
H5FD_sec2_query(const H5FD_t *_file, unsigned long *flags /* out */)
{
- const H5FD_sec2_t *file = (const H5FD_sec2_t *)_file; /* sec2 VFD info */
+ const H5FD_sec2_t *file = (const H5FD_sec2_t *)_file; /* sec2 VFD info */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_sec2_query)
/* Set the VFL feature flags that this driver supports */
if(flags) {
*flags = 0;
- *flags |= H5FD_FEAT_AGGREGATE_METADATA; /* OK to aggregate metadata allocations */
- *flags |= H5FD_FEAT_ACCUMULATE_METADATA; /* OK to accumulate metadata for faster writes */
- *flags |= H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */
- *flags |= H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
- *flags |= H5FD_FEAT_POSIX_COMPAT_HANDLE; /* VFD handle is POSIX I/O call compatible */
+ *flags |= H5FD_FEAT_AGGREGATE_METADATA; /* OK to aggregate metadata allocations */
+ *flags |= H5FD_FEAT_ACCUMULATE_METADATA; /* OK to accumulate metadata for faster writes */
+ *flags |= H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */
+ *flags |= H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
+ *flags |= H5FD_FEAT_POSIX_COMPAT_HANDLE; /* VFD handle is POSIX I/O call compatible */
/* Check for flags that are set by h5repart */
if(file->fam_to_sec2)
@@ -547,24 +567,25 @@ 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: Success: The end-of-address marker.
+ * Failure: HADDR_UNDEF
*
- * 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)
{
- const H5FD_sec2_t *file = (const H5FD_sec2_t *)_file;
+ const H5FD_sec2_t *file = (const H5FD_sec2_t *)_file;
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_sec2_get_eoa)
@@ -573,24 +594,25 @@ 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: Success: 0
+ * Failure: -1
*
- * 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)
{
- H5FD_sec2_t *file = (H5FD_sec2_t *)_file;
+ H5FD_sec2_t *file = (H5FD_sec2_t *)_file;
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_sec2_set_eoa)
@@ -601,18 +623,18 @@ 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 Unix 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 Unix 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
*
*-------------------------------------------------------------------------
@@ -620,7 +642,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_NOFUNC(H5FD_sec2_get_eof)
@@ -660,17 +682,17 @@ 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: Zero. Result is stored in caller-supplied
+ * buffer BUF.
+ * Failure: -1, Contents of buffer BUF are undefined.
*
- * Programmer: Robb Matzke
+ * Programmer: Robb Matzke
* Thursday, July 29, 1999
*
*-------------------------------------------------------------------------
@@ -678,11 +700,10 @@ done:
/* 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*/)
+ haddr_t addr, size_t size, void *buf /*out*/)
{
- H5FD_sec2_t *file = (H5FD_sec2_t *)_file;
- ssize_t nbytes;
- 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(H5FD_sec2_read)
@@ -704,33 +725,46 @@ H5FD_sec2_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id,
HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position")
} /* end if */
- /*
- * Read data, being careful of interrupted system calls, partial results,
+ /* Read data, being careful of interrupted system calls, partial results,
* and the end of the file.
*/
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 */
+
+ /* 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;
+ else
+ bytes_in = (h5_sec2_io_t)size;
+
do {
- nbytes = HDread(file->fd, buf, size);
- } while(-1 == nbytes && EINTR == errno);
- if(-1 == nbytes) { /* error */
+ bytes_read = HDread(file->fd, buf, bytes_in);
+ } while(-1 == bytes_read && EINTR == errno);
+
+ if(-1 == bytes_read) { /* error */
int myerrno = errno;
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);
} /* end if */
- if(0 == nbytes) {
+
+ if(0 == bytes_read) {
/* end of file but not end of format address space */
HDmemset(buf, 0, size);
break;
} /* end if */
- HDassert(nbytes >= 0);
- HDassert((size_t)nbytes <= size);
- H5_CHECK_OVERFLOW(nbytes, ssize_t, size_t);
- size -= (size_t)nbytes;
- H5_CHECK_OVERFLOW(nbytes, ssize_t, haddr_t);
- addr += (haddr_t)nbytes;
- buf = (char *)buf + nbytes;
+
+ HDassert(bytes_read >= 0);
+ HDassert((size_t)bytes_read <= size);
+
+ size -= (size_t)bytes_read;
+ addr += (haddr_t)bytes_read;
+ buf = (char *)buf + bytes_read;
} /* end while */
/* Update current position */
@@ -749,28 +783,27 @@ 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: Success: Zero
+ * Failure: -1
*
- * 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)
+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)
{
- H5FD_sec2_t *file = (H5FD_sec2_t *)_file;
- ssize_t nbytes;
- 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(H5FD_sec2_write)
@@ -791,28 +824,40 @@ H5FD_sec2_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, had
HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position")
} /* end if */
- /*
- * Write the data, being careful of interrupted system calls and partial
+ /* Write the data, being careful of interrupted system calls and partial
* results
*/
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 */
+
+ /* 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;
+ else
+ bytes_in = (h5_sec2_io_t)size;
+
do {
- nbytes = HDwrite(file->fd, buf, size);
- } while(-1 == nbytes && EINTR == errno);
- if(-1 == nbytes) { /* error */
+ bytes_wrote = HDwrite(file->fd, buf, bytes_in);
+ } while(-1 == bytes_wrote && EINTR == errno);
+
+ if(-1 == bytes_wrote) { /* error */
int myerrno = errno;
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);
} /* end if */
- HDassert(nbytes > 0);
- HDassert((size_t)nbytes <= size);
- H5_CHECK_OVERFLOW(nbytes, ssize_t, size_t);
- size -= (size_t)nbytes;
- H5_CHECK_OVERFLOW(nbytes, ssize_t, haddr_t);
- addr += (haddr_t)nbytes;
- buf = (const char *)buf + nbytes;
+
+ HDassert(bytes_wrote > 0);
+ HDassert((size_t)bytes_wrote <= size);
+
+ size -= (size_t)bytes_wrote;
+ addr += (haddr_t)bytes_wrote;
+ buf = (const char *)buf + bytes_wrote;
} /* end while */
/* Update current position and eof */
@@ -833,15 +878,15 @@ 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: Success: Non-negative
+ * Failure: Negative
*
- * Programmer: Robb Matzke
+ * Programmer: Robb Matzke
* Wednesday, August 4, 1999
*
*-------------------------------------------------------------------------
@@ -860,17 +905,30 @@ H5FD_sec2_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t UNUSED closing)
/* Extend the file to make sure it's large enough */
if(!H5F_addr_eq(file->eoa, file->eof)) {
#ifdef H5_HAVE_WIN32_API
- HFILE filehandle; /* Windows file handle */
- LARGE_INTEGER li; /* 64-bit integer for SetFilePointer() call */
-
- /* Map the posix file handle to a Windows file handle */
- filehandle = _get_osfhandle(file->fd);
-
- /* Translate 64-bit integers into form Windows wants */
- /* [This algorithm is from the Windows documentation for SetFilePointer()] */
- li.QuadPart = (LONGLONG)file->eoa;
- (void)SetFilePointer((HANDLE)filehandle, li.LowPart, &li.HighPart, FILE_BEGIN);
- if(SetEndOfFile((HANDLE)filehandle) == 0)
+ LARGE_INTEGER li; /* 64-bit (union) integer for SetFilePointer() call */
+ DWORD dwPtrLow; /* Low-order pointer bits from SetFilePointer()
+ * Only used as an error code here.
+ */
+ DWORD dwError; /* DWORD error code from GetLastError() */
+ BOOL bError; /* Boolean error flag */
+
+ /* Windows uses this odd QuadPart union for 32/64-bit portability */
+ li.QuadPart = (__int64)file->eoa;
+
+ /* Extend the file to make sure it's large enough.
+ *
+ * Since INVALID_SET_FILE_POINTER can technically be a valid return value
+ * from SetFilePointer(), we also need to check GetLastError().
+ */
+ dwPtrLow = SetFilePointer(file->hFile, li.LowPart, &li.HighPart, FILE_BEGIN);
+ if(INVALID_SET_FILE_POINTER == dwPtrLow) {
+ dwError = GetLastError();
+ if(dwError != NO_ERROR )
+ HGOTO_ERROR(H5E_FILE, H5E_FILEOPEN, FAIL, "unable to set file pointer")
+ }
+
+ bError = SetEndOfFile(file->hFile);
+ if(0 == bError)
HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")
#else /* H5_HAVE_WIN32_API */
#ifdef H5_VMS
@@ -879,7 +937,6 @@ H5FD_sec2_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t UNUSED closing)
if(-1 == HDlseek(file->fd, (HDoff_t)0, SEEK_SET))
HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position")
#endif
-
if(-1 == HDftruncate(file->fd, (HDoff_t)file->eoa))
HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")
#endif /* H5_HAVE_WIN32_API */
diff --git a/src/H5FDwindows.c b/src/H5FDwindows.c
index ba5bd9b..105ac14 100644
--- a/src/H5FDwindows.c
+++ b/src/H5FDwindows.c
@@ -13,240 +13,63 @@
* access to either file, you may request a copy from help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-/*
- * Programmer: Scott Wegner <swegner@hdfgroup.org>
- * Based on code by Robb Matzke
- * May 24, 2007
- *
- * Purpose: We would like to create a driver specifically for Windows
- * to utilize the Win32 API, and reduce the maintenence demands
- * for the other file drivers. Our other motivation is that
- * the Windows system calls of the existing sec2 driver differ
- * from those on other platforms, and are not 64-bit compatible.
- * From the start, this will have the structure very similar
- * to our sec2 driver, but make system calls more similar to
- * our stdio driver.
- */
-
-/* Interface initialization */
-#define H5_INTERFACE_INIT_FUNC H5FD_windows_init_interface
-
-
-#include "H5private.h" /* Generic Functions */
-#include "H5Eprivate.h" /* Error handling */
-#include "H5Fprivate.h" /* File access */
-#include "H5FDprivate.h" /* File drivers */
-#include "H5FDwindows.h" /* Windows 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 "H5FDwindows.h" /* Windows file driver */
+#include "H5FDsec2.h" /* Windows file driver */
+#include "H5FLprivate.h" /* Free Lists */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Pprivate.h" /* Property lists */
#ifdef H5_HAVE_WINDOWS
-/* The driver identification number, initialized at runtime */
-static hid_t H5FD_WINDOWS_g = 0;
-
-/* File operations */
-#define OP_UNKNOWN 0
-#define OP_READ 1
-#define OP_WRITE 2
-
-/*
- * 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 file). The `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.
- */
-typedef struct H5FD_windows_t {
- H5FD_t pub; /*public stuff, must be first */
- /*
- * .NET doesn't support our 64-bit safe stdio functions,
- * so we will use io.h functions instead.
- */
-#ifndef WINDOWS_USE_STDIO
- int fd; /*the file descriptor */
-#else
- FILE *fp; /*the file handle */
-#endif /*MSC_VER */
- haddr_t eoa; /*end of allocated region */
- haddr_t eof; /*end of file; current file size*/
- haddr_t pos; /*current file I/O position */
- int op; /*last operation */
- unsigned write_access; /*flag to indicate the file was opened with write access */
- /*
- * On H5_HAVE_WIN32_API the low-order word of a unique identifier associated with the
- * file and the volume serial number uniquely identify a file. This number
- * may change when the system is restarted or when the
- * file is opened. After a process opens a file, the identifier is
- * constant until the file is closed. An application can use this
- * identifier and the volume serial number to determine whether two
- * handles refer to the same file.
- */
- DWORD fileindexlo;
- DWORD fileindexhi;
- DWORD volumeserialnumber;
-
- /* Information from properties set by 'h5repart' tool */
- hbool_t fam_to_sec2; /* Whether to eliminate the family driver info
- * and convert this file to a single file */
-} H5FD_windows_t;
-
-
-/* These are used by the macros below */
-#define file_offset_t __int64
-#define fseek_offset_t __int64
-
-/*
- * These macros check for overflow of various quantities. These macros
- * assume that fseek_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.
- *
- * 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.
- */
-#define MAXADDR (((haddr_t)1<<(8*sizeof(file_offset_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) || \
- (fseek_offset_t)((A)+(Z))<(fseek_offset_t)(A))
-
-/* Prototypes */
-static H5FD_t *H5FD_windows_open(const char *name, unsigned flags, hid_t fapl_id,
- haddr_t maxaddr);
-static herr_t H5FD_windows_close(H5FD_t *_file);
-static int H5FD_windows_cmp(const H5FD_t *_f1, const H5FD_t *_f2);
-static herr_t H5FD_windows_query(const H5FD_t *_f1, unsigned long *flags);
-static haddr_t H5FD_windows_alloc(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id,
- hsize_t size);
-static haddr_t H5FD_windows_get_eoa(const H5FD_t *_file, H5FD_mem_t type);
-static herr_t H5FD_windows_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr);
-static haddr_t H5FD_windows_get_eof(const H5FD_t *_file);
-static herr_t H5FD_windows_get_handle(H5FD_t *_file, hid_t fapl, void** file_handle);
-static herr_t H5FD_windows_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr,
- size_t size, void *buf);
-static herr_t H5FD_windows_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr,
- size_t size, const void *buf);
-static herr_t H5FD_windows_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing);
-static herr_t H5FD_windows_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing);
-
-static const H5FD_class_t H5FD_windows_g = {
- "windows", /*name */
- MAXADDR, /*maxaddr */
- H5F_CLOSE_WEAK, /* fc_degree */
- 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_windows_open, /*open */
- H5FD_windows_close, /*close */
- H5FD_windows_cmp, /*cmp */
- H5FD_windows_query, /*query */
- NULL, /*get_type_map */
- NULL, /*alloc */
- NULL, /*free */
- H5FD_windows_get_eoa, /*get_eoa */
- H5FD_windows_set_eoa, /*set_eoa */
- H5FD_windows_get_eof, /*get_eof */
- H5FD_windows_get_handle, /*get_handle */
- H5FD_windows_read, /*read */
- H5FD_windows_write, /*write */
- H5FD_windows_flush, /*flush */
- H5FD_windows_truncate, /*truncate */
- NULL, /*lock */
- NULL, /*unlock */
- H5FD_FLMAP_SINGLE /*fl_map */
-};
-
-/* Declare a free list to manage the H5FD_windows_t struct */
-H5FL_DEFINE_STATIC(H5FD_windows_t);
-
-/*--------------------------------------------------------------------------
-NAME
- H5FD_windows_init_interface -- Initialize interface-specific information
-USAGE
- herr_t H5FD_windows_init_interface()
-
-RETURNS
- Non-negative on success/Negative on failure
-DESCRIPTION
- Initializes any interface-specific data or routines. (Just calls
- H5FD_windows_init currently).
-
---------------------------------------------------------------------------*/
-static herr_t
-H5FD_windows_init_interface(void)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_windows_init_interface)
-
- FUNC_LEAVE_NOAPI(H5FD_windows_init())
-} /* H5FD_windows_init_interface() */
-
+
/*-------------------------------------------------------------------------
- * Function: H5FD_windows_init
+ * Function: H5FD_windows_init
*
- * Purpose: Initialize this driver by registering the driver with the
- * library.
+ * Purpose: Initialize this driver by registering the driver with the
+ * library. Note that this really initializes the underlying
+ * SEC2 driver.
*
- * Return: Success: The driver ID for the windows driver.
- * Failure: Negative.
+ * Return: Success: The driver ID for the windows(sec2) driver.
+ * Failure: Negative.
*
- * Programmer: Scott Wegner
- * Based on code by Robb Matzke
- * Thursday, May 24, 2007
+ * Programmer: Dana Robinson
+ * October 12, 2011
*
*-------------------------------------------------------------------------
*/
hid_t
H5FD_windows_init(void)
{
- hid_t ret_value; /* Return value */
+ hid_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5FD_windows_init, FAIL)
- if(H5I_VFL != H5I_get_type(H5FD_WINDOWS_g))
- H5FD_WINDOWS_g = H5FD_register(&H5FD_windows_g, sizeof(H5FD_class_t), FALSE);
+ if(H5I_VFL != H5I_get_type(H5FD_SEC2_g))
+ H5FD_SEC2_g = H5FD_register(&H5FD_sec2_g, sizeof(H5FD_class_t), FALSE);
/* Set return value */
- ret_value = H5FD_WINDOWS_g;
+ ret_value = H5FD_SEC2_g;
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_windows_init() */
+} /* end H5FD_sec2_init() */
+
/*---------------------------------------------------------------------------
- * Function: H5FD_windows_term
- *
- * Purpose: Shut down the VFD
+ * Function: H5FD_windows_term
*
- * Return: <none>
+ * Purpose: Shut down the VFD. Note that this really shuts down the
+ * underlying SEC2 driver.
*
- * Programmer: Scott Wegner
- * Based on code by Quincey Koziol
- * Thursday, May 24 2007
+ * Returns: <none>
*
- * Modification:
+ * Programmer: Dana Robinson
+ * October 12, 2011
*
*---------------------------------------------------------------------------
*/
@@ -256,25 +79,30 @@ H5FD_windows_term(void)
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_windows_term)
/* Reset VFL ID */
- H5FD_WINDOWS_g=0;
+ H5FD_SEC2_g = 0;
FUNC_LEAVE_NOAPI_VOID
} /* end H5FD_windows_term() */
+
+
/*-------------------------------------------------------------------------
- * Function: H5Pset_fapl_windows
+ * Function: H5Pset_fapl_windows
*
- * Purpose: Modify the file access property list to use the H5FD_WINDOWS
- * driver defined in this source file. There are no driver
- * specific properties.
+ * Purpose: Modify the file access property list to use the H5FD_WINDOWS
+ * driver defined in this source file. There are no driver
+ * specific properties.
*
- * Return: Non-negative on success/Negative on failure
+ * NOTE: The Windows VFD was merely a merge of the SEC2 and STDIO drivers
+ * so it has been retired. Selecting the Windows VFD will actually
+ * set the SEC2 VFD (though for backwards compatibility, we'll keep
+ * the H5FD_WINDOWS symbol).
*
- * Programmer: Scott Wegner
- * Based on code by Robb Matzke
- * Thursday, May 24 2007
*
- * Modifications:
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Dana Robinson
+ * October 10, 2011
*
*-------------------------------------------------------------------------
*/
@@ -287,797 +115,14 @@ H5Pset_fapl_windows(hid_t fapl_id)
FUNC_ENTER_API(H5Pset_fapl_windows, FAIL)
H5TRACE1("e", "i", fapl_id);
- if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS)))
+ if(NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
- ret_value= H5P_set_driver(plist, H5FD_WINDOWS, NULL);
+ ret_value = H5P_set_driver(plist, H5FD_WINDOWS, NULL);
done:
FUNC_LEAVE_API(ret_value)
-}
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_windows_open
- *
- * Purpose: Create and/or opens a Windows 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
- *
- * Programmer: Scott Wegner
- * Based on code by Robb Matzke
- * Thursday, May 24 2007
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-/* ARGSUSED */
-static H5FD_t *
-H5FD_windows_open(const char *name, unsigned flags, hid_t UNUSED fapl_id,
- haddr_t maxaddr)
-{
- int fd = -1;
- FILE *f = NULL;
- H5FD_windows_t *file = NULL;
- HANDLE filehandle;
- struct _BY_HANDLE_FILE_INFORMATION fileinfo;
- H5FD_t *ret_value;
- struct _stati64 sb;
-#ifndef WINDOWS_USE_STDIO
- int o_flags;
-#else
- unsigned write_access = 0;
-#endif /* WINDOWS_USE_STDIO */
-
- FUNC_ENTER_NOAPI(H5FD_windows_open, NULL)
-
- /* Sanity check on file offsets */
- assert(sizeof(file_offset_t)>=sizeof(size_t));
-
- /* Check arguments */
- if (!name || !*name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid file name")
- if (0==maxaddr || HADDR_UNDEF==maxaddr)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr")
- if (ADDR_OVERFLOW(maxaddr))
- HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, NULL, "bogus maxaddr")
-
-#ifndef WINDOWS_USE_STDIO
- /* Build the open flags */
- o_flags = (H5F_ACC_RDWR & flags) ? O_RDWR : O_RDONLY;
- if (H5F_ACC_TRUNC & flags) o_flags |= O_TRUNC;
- if (H5F_ACC_CREAT & flags) o_flags |= O_CREAT;
- if (H5F_ACC_EXCL & flags) o_flags |= O_EXCL;
- /* Windows needs O_BINARY to correctly handle eol characters */
- o_flags |= O_BINARY;
-
- /* Open the file */
- if ((fd=_open(name, o_flags, 0666))<0)
- HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file")
- if (_fstati64(fd, &sb) == -1)
- HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, "unable to fstat file")
-
-#else /* WINDOWS_USE_STDIO */
- /* Translate our flags into a mode, and open the file */
- if (_access_s(name, F_OK)) {
- if ((flags & H5F_ACC_CREAT) && (flags & H5F_ACC_RDWR)) {
- f = fopen(name, "wb+");
- write_access=1; /* Note the write access */
- }
- else
- HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "file doesn't exist and CREAT wasn't specified")
- } else if ((flags & H5F_ACC_CREAT) && (flags & H5F_ACC_EXCL)) {
- HSYS_GOTO_ERROR(H5E_FILE, H5E_FILEEXISTS, NULL, "file exists but CREAT and EXCL were specified")
- } else if (flags & H5F_ACC_RDWR) {
- if (flags & H5F_ACC_TRUNC)
- f = fopen(name, "wb+");
- else
- f = fopen(name, "rb+");
- write_access=1; /* Note the write access */
- } else
- f = fopen(name, "rb");
-
- if (!f)
- HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "fsopen failed")
-
- if (_stati64(name, &sb) == -1)
- HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, "unable to stat file")
-#endif /* WINDOWS_USE_STDIO */
-
- /* Create the new file struct */
- if (NULL==(file=H5FL_CALLOC(H5FD_windows_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate file struct")
-
- H5_ASSIGN_OVERFLOW(file->eof,sb.st_size,h5_stat_size_t,haddr_t);
- file->pos = HADDR_UNDEF;
- file->op = OP_UNKNOWN;
-
-#ifndef WINDOWS_USE_STDIO
- file->fd = fd;
-#else
- file->fp = f;
- if((fd = _fileno(f)) == -1)
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to get file descriptor for file")
- file->write_access=write_access; /* Note the write_access for later */
-#endif /* WINDOWS_USE_STDIO */
-
- if( (filehandle = (HANDLE)_get_osfhandle(fd)) == INVALID_HANDLE_VALUE)
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to get file handle for file")
- if(!GetFileInformationByHandle(filehandle, &fileinfo))
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to get file information")
- file->fileindexhi = fileinfo.nFileIndexHigh;
- file->fileindexlo = fileinfo.nFileIndexLow;
- file->volumeserialnumber = fileinfo.dwVolumeSerialNumber;
-
- /* Check for non-default FAPL */
- if(H5P_FILE_ACCESS_DEFAULT != fapl_id) {
- H5P_genplist_t *plist; /* Property list pointer */
-
- /* Get the FAPL */
- if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
- HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, NULL, "not a file access property list")
-
- /* This step is for h5repart tool only. If user wants to change file driver from
- * family to sec2 while using h5repart, this private property should be set so that
- * in the later step, the library can ignore the family driver information saved
- * in the superblock.
- */
- if(H5P_exist_plist(plist, H5F_ACS_FAMILY_TO_SEC2_NAME) > 0)
- if(H5P_get(plist, H5F_ACS_FAMILY_TO_SEC2_NAME, &file->fam_to_sec2) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get property of changing family to sec2")
- } /* end if */
-
- /* Set return value */
- ret_value=(H5FD_t*)file;
-
-done:
- if(ret_value==NULL) {
-#ifndef WINDOWS_USE_STDIO
- if(fd>=0)
- _close(fd);
-#else
- if(f)
- fclose(file->fp);
-#endif /* WINDOWS_USE_STDIO */
- } /* end if */
-
- FUNC_LEAVE_NOAPI(ret_value)
-}
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_windows_close
- *
- * Purpose: Closes a Windows file.
- *
- * Return: Success: 0
- *
- * Failure: -1, file not closed.
- *
- * Programmer: Scott Wegner
- * Based on code by Robb Matzke
- * Thursday, May 24 2007
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5FD_windows_close(H5FD_t *_file)
-{
- H5FD_windows_t *file = (H5FD_windows_t*)_file;
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_windows_close, FAIL)
-
-#ifndef WINDOWS_USE_STDIO
- if (_close(file->fd)<0)
-#else
- if (fclose(file->fp)<0)
-#endif /* WINDOWS_USE_STDIO */
- HSYS_GOTO_ERROR(H5E_IO, H5E_CANTCLOSEFILE, FAIL, "unable to close file")
-
- H5FL_FREE(H5FD_windows_t,file);
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_windows_cmp
- *
- * 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).
- *
- * Programmer: Scott Wegner
- * Based on code by Robb Matzke
- * Thursday, May 24 2007
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static int
-H5FD_windows_cmp(const H5FD_t *_f1, const H5FD_t *_f2)
-{
- const H5FD_windows_t *f1 = (const H5FD_windows_t*)_f1;
- const H5FD_windows_t *f2 = (const H5FD_windows_t*)_f2;
- int ret_value=0;
-
- FUNC_ENTER_NOAPI(H5FD_windows_cmp, H5FD_VFD_DEFAULT)
-
- if (f1->volumeserialnumber < f2->volumeserialnumber) HGOTO_DONE(-1)
- if (f1->volumeserialnumber > f2->volumeserialnumber) HGOTO_DONE(1)
-
- if (f1->fileindexhi < f2->fileindexhi) HGOTO_DONE(-1)
- if (f1->fileindexhi > f2->fileindexhi) HGOTO_DONE(1)
-
- if (f1->fileindexlo < f2->fileindexlo) HGOTO_DONE(-1)
- if (f1->fileindexlo > f2->fileindexlo) HGOTO_DONE(1)
-
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_windows_query
- *
- * Purpose: Set the flags that this VFL driver is capable of supporting.
- * (listed in H5FDpublic.h)
- *
- * Return: Success: non-negative
- *
- * Failure: negative
- *
- * Programmer: Scott Wegner
- Based on code by Quincey Koziol
- * Thursday, May 24 2007
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5FD_windows_query(const H5FD_t *_file, unsigned long *flags /* out */)
-{
- const H5FD_windows_t *file = (const H5FD_windows_t*)_file; /* windows VFD info */
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_windows_query)
-
- /* Set the VFL feature flags that this driver supports */
- if(flags) {
- *flags = 0;
- *flags|=H5FD_FEAT_AGGREGATE_METADATA; /* OK to aggregate metadata allocations */
- *flags|=H5FD_FEAT_ACCUMULATE_METADATA; /* OK to accumulate metadata for faster writes */
- *flags|=H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */
- *flags|=H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
-
- /* Check for flags that are set by h5repart */
- if(file->fam_to_sec2)
- *flags |= H5FD_FEAT_IGNORE_DRVRINFO; /* Ignore the driver info when file is opened (which eliminates it) */
- } /* end if */
-
-done:
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5FD_windows_query() */
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_windows_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.
- *
- * Return: Success: The end-of-address marker.
- *
- * Failure: HADDR_UNDEF
- *
- * Programmer: Scott Wegner
- * Based on code by Robb Matzke
- * Thursday, May 24 2007
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static haddr_t
-H5FD_windows_get_eoa(const H5FD_t *_file, H5FD_mem_t UNUSED type)
-{
- const H5FD_windows_t *file = (const H5FD_windows_t*)_file;
- haddr_t ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_windows_get_eoa, HADDR_UNDEF)
-
- /* Set return value */
- ret_value=file->eoa;
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_windows_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.
- *
- * Return: Success: 0
- *
- * Failure: -1
- *
- * Programmer: Scott Wegner
- * Based on code by Robb Matzke
- * Thursday, July 29, 1999
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5FD_windows_set_eoa(H5FD_t *_file, H5FD_mem_t UNUSED type, haddr_t addr)
-{
- H5FD_windows_t *file = (H5FD_windows_t*)_file;
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_windows_set_eoa, FAIL)
-
- file->eoa = addr;
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_windows_get_eof
- *
- * Purpose: Returns the end-of-file marker, which is the greater of
- * either the Windows 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 Unix file
- * or the HDF5 file.
- *
- * Failure: HADDR_UNDEF
- *
- * Programmer: Scott Wegner
- * Based on code by Robb Matzke
- * Thursday, May 24 2007
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static haddr_t
-H5FD_windows_get_eof(const H5FD_t *_file)
-{
- const H5FD_windows_t *file = (const H5FD_windows_t*)_file;
- haddr_t ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_windows_get_eof, HADDR_UNDEF)
-
- /* Set return value */
- ret_value=MAX(file->eof, file->eoa);
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_windows_get_handle
- *
- * Purpose: Returns the file handle of windows file driver.
- *
- * Returns: Non-negative if succeed or negative if fails.
- *
- * Programmer: Scott Wegner
- Based on code by Raymond Lu
- * Thursday, May 24 2007
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-/* ARGSUSED */
-static herr_t
-H5FD_windows_get_handle(H5FD_t *_file, hid_t UNUSED fapl, void** file_handle)
-{
- H5FD_windows_t *file = (H5FD_windows_t *)_file;
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI(H5FD_windows_get_handle, FAIL)
-
- if(!file_handle)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file handle not valid")
-#ifndef WINDOWS_USE_STDIO
- *file_handle = &(file->fd);
-#else
- *file_handle = &(file->fp);
-#endif /* WINDOWS_USE_STDIO */
- if(*file_handle==NULL)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "get handle failed")
-
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_windows_alloc
- *
- * Purpose: Allocates file memory.
- *
- * Return: Success: Address of new memory
- *
- * Failure: HADDR_UNDEF
- *
- * Programmer: Scott Wegner
- Based on code by Raymond Lu
- * Thursday, May 24 2007
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static haddr_t
-H5FD_windows_alloc(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, hsize_t size)
-{
- H5FD_windows_t *file = (H5FD_windows_t*)_file;
- haddr_t addr;
- haddr_t ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_windows_alloc, HADDR_UNDEF)
-
- /* Compute the address for the block to allocate */
- addr = file->eoa;
-
- /* Check if we need to align this block */
- if(size >= file->pub.threshold) {
- /* Check for an already aligned block */
- if((addr % file->pub.alignment) != 0)
- addr = ((addr / file->pub.alignment) + 1) * file->pub.alignment;
- }
-
-
- file->eoa = addr + size;
-
- /* Set return value */
- ret_value = addr;
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_windows_read
- *
- * 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.
- *
- * Programmer: Scott Wegner
- Based on code by Robb Matzke
- * Thursday, May 24 2007
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-/* ARGSUSED */
-static herr_t
-H5FD_windows_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr,
- size_t size, void *buf/*out*/)
-{
- H5FD_windows_t *file = (H5FD_windows_t*)_file;
- int nbytes;
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_windows_read, FAIL)
-
- assert(file && file->pub.cls);
- assert(buf);
-
- /* Check for overflow conditions */
- if (HADDR_UNDEF==addr)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined")
- if (REGION_OVERFLOW(addr, size))
- HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow")
- if((addr + size) > file->eoa)
- HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow")
-
- /* Seek to the correct location */
- if ((addr!=file->pos || OP_READ!=file->op))
-#ifndef WINDOWS_USE_STDIO
- if (_lseeki64(file->fd, addr, SEEK_SET) == -1) {
-#else
- if (_fseeki64(file->fp, addr, SEEK_SET) == -1) {
-#endif /* WINDOWS_USE_STDIO */
- file->op = OP_UNKNOWN;
- file->pos = HADDR_UNDEF;
- HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position")
- }
-
- /*
- * Read data, being careful of interrupted system calls, partial results,
- * and the end of the file.
- */
- while (size>0) {
-#ifndef WINDOWS_USE_STDIO
- do {
- nbytes = _read(file->fd, buf, (unsigned)(size <= WINDOWS_MAX_BUF ? size: WINDOWS_MAX_BUF));
- } while (-1==nbytes && EINTR==errno);
- if (-1==nbytes) /* error */
- HSYS_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed")
- if (0==nbytes) {
- /* end of file but not end of format address space */
- HDmemset(buf, 0, size);
- break;
- }
-#else
- do {
- nbytes = fread(buf,(size_t)1,(size <= WINDOWS_MAX_BUF ? size: WINDOWS_MAX_BUF),file->fp);
- } while (!nbytes && EINTR==errno);
- if(!nbytes) {
- if (ferror(file->fp)) /* error */
- HSYS_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed")
- if (feof(file->fp)) {
- /* end of file but not end of format address space */
- HDmemset(buf, 0, size);
- break;
- }
- }
-#endif /* WINDOWS_USE_STDIO */
- assert(nbytes>=0);
- assert((size_t)nbytes<=size);
- H5_CHECK_OVERFLOW(nbytes,ssize_t,size_t);
- size -= (size_t)nbytes;
- H5_CHECK_OVERFLOW(nbytes,ssize_t,haddr_t);
- addr += (haddr_t)nbytes;
- buf = (char*)buf + nbytes;
- }
-
- /* Update current position */
- file->pos = addr;
- file->op = OP_READ;
-
-done:
- if(ret_value<0) {
- /* Reset last file I/O information */
- file->pos = HADDR_UNDEF;
- file->op = OP_UNKNOWN;
- } /* end if */
-
- FUNC_LEAVE_NOAPI(ret_value)
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_windows_write
- *
- * 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
- *
- * Programmer: Scott Wegner
- * Based on code by Robb Matzke
- * Thursday, May 24 2007
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-/* ARGSUSED */
-static herr_t
-H5FD_windows_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr,
- size_t size, const void *buf)
-{
- H5FD_windows_t *file = (H5FD_windows_t*)_file;
- ssize_t nbytes;
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_windows_write, FAIL)
-
- assert(file && file->pub.cls);
- assert(buf);
-
- /* Check for overflow conditions */
- if (HADDR_UNDEF==addr)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined")
- if (REGION_OVERFLOW(addr, size))
- HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow")
- if (addr+size>file->eoa)
- HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow")
-
- /* Seek to the correct location */
- if ((addr!=file->pos || OP_WRITE!=file->op))
- {
-#ifndef WINDOWS_USE_STDIO
- if (_lseeki64(file->fd, addr, SEEK_SET) == -1) {
-#else
- if (_fseeki64(file->fp, addr, SEEK_SET) == -1) {
-#endif /* WINDOWS_USE_STDIO */
- file->op = OP_UNKNOWN;
- file->pos = HADDR_UNDEF;
- HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position")
- }
- }
-
- /*
- * Write the data, being careful of interrupted system calls and partial
- * results
- */
- while (size>0) {
- do {
-#ifndef WINDOWS_USE_STDIO
- nbytes = _write(file->fd, buf, (unsigned)(size <= WINDOWS_MAX_BUF ? size: WINDOWS_MAX_BUF));
- } while (-1==nbytes && EINTR==errno);
- if (-1==nbytes) /* error */
-#else
-
-
- /* Write 1GB or less at a time */
- nbytes = fwrite(buf, 1, (size <= WINDOWS_MAX_BUF ? size: WINDOWS_MAX_BUF),file->fp);
- } while (!nbytes && EINTR==errno);
- if (!nbytes) /* error */
-#endif /* WINDOWS_USE_STDIO */
- HSYS_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed")
- assert(nbytes>0);
- assert((size_t)nbytes<=size);
- H5_CHECK_OVERFLOW(nbytes,ssize_t,size_t);
- size -= (size_t)nbytes;
- H5_CHECK_OVERFLOW(nbytes,ssize_t,haddr_t);
- addr += (haddr_t)nbytes;
- buf = (const char*)buf + nbytes;
- }
-
- /* Update current position and eof */
- file->pos = addr;
- file->op = OP_WRITE;
- if (file->pos>file->eof)
- file->eof = file->pos;
-
-done:
- if(ret_value<0) {
- /* Reset last file I/O information */
- file->pos = HADDR_UNDEF;
- file->op = OP_UNKNOWN;
- } /* end if */
-
- FUNC_LEAVE_NOAPI(ret_value)
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_windows_flush
- *
- * Purpose: Makes sure that the true file size is the same (or larger)
- * than the end-of-address.
- *
- * Return: Success: Non-negative
- * Failure: Negative
- *
- * Programmer: Scott Wegner
- * Based on code by Robb Matzke
- * Thursday, May 24 2007
- *
- *-------------------------------------------------------------------------
- */
-/* ARGSUSED */
-static herr_t
-H5FD_windows_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned closing)
-{
- H5FD_windows_t *file = (H5FD_windows_t*)_file;
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_windows_flush, FAIL)
-
- HDassert(file);
-
- /* Only try to flush if we have write access */
- if(file->write_access) {
- /* Flush */
- if(!closing) {
-#ifdef WINDOWS_USE_STDIO
- if(fflush(file->fp) == EOF)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "fflush failed")
-#endif /* WINDOWS_USE_STDIO */
-
- /* Reset last file I/O information */
- file->pos = HADDR_UNDEF;
- file->op = OP_UNKNOWN;
- } /* end if */
- } /* end if */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_windows_flush() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5FD_windows_truncate
- *
- * Purpose: Makes sure that the true file size is the same (or larger)
- * than the end-of-address.
- *
- * Return: Success: Non-negative
- * Failure: Negative
- *
- * Programmer: Scott Wegner
- * Based on code by Robb Matzke
- * Thursday, May 24 2007
- *
- *-------------------------------------------------------------------------
- */
-/* ARGSUSED */
-static herr_t
-H5FD_windows_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t UNUSED closing)
-{
- H5FD_windows_t *file = (H5FD_windows_t*)_file;
-#ifndef WINDOWS_USE_STDIO
- LARGE_INTEGER li;
- HANDLE filehandle;
-#else
- int fd;
-#endif /* WINDOWS_USE_STDIO */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5FD_windows_truncate, FAIL)
-
- HDassert(file);
-
- if(file->eoa != file->eof) {
-#ifndef WINDOWS_USE_STDIO
- /* Extend the file to make sure it's large enough */
- if((filehandle = (HANDLE)_get_osfhandle(file->fd)) == INVALID_HANDLE_VALUE)
- HGOTO_ERROR(H5E_FILE, H5E_FILEOPEN, FAIL, "unable to get file handle for file")
-
- li.QuadPart = (__int64)file->eoa;
- (void)SetFilePointer((HANDLE)filehandle, li.LowPart, &li.HighPart, FILE_BEGIN);
- if(SetEndOfFile(filehandle) == 0)
- HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")
-#else /* WINDOWS_USE_STDIO */
- /* Only try to flush if we have write access */
- if(!file->write_access)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "cannot flush without write access")
-
- if((fd = _fileno(file->fp)) == -1)
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to get file descriptor for file")
- if(_chsize_s(fd, file->eoa))
- HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly")
-#endif /* WINDOWS_USE_STDIO */
-
- /* Update the eof value */
- file->eof = file->eoa;
-
- /* Reset last file I/O information */
- file->pos = HADDR_UNDEF;
- file->op = OP_UNKNOWN;
- } /* end if */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_windows_truncate() */
+} /* end H5Pset_fapl_windows() */
#endif /* H5_HAVE_WINDOWS */
diff --git a/src/H5FDwindows.h b/src/H5FDwindows.h
index 8277f149..ecc28a7 100644
--- a/src/H5FDwindows.h
+++ b/src/H5FDwindows.h
@@ -24,6 +24,7 @@
#define H5FDwindows_H
#include "H5Ipublic.h"
+#include "H5FDsec2.h"
#define H5FD_WINDOWS (H5FD_windows_init())
@@ -31,8 +32,14 @@
extern "C" {
#endif
-H5_DLL hid_t H5FD_windows_init(void);
-H5_DLL void H5FD_windows_term(void);
+/* The code behind the windows VFD has been removed and the windows
+ * VFD initialization has been redirected to the SEC2 driver. The
+ * "Windows" VFD was actually identical to the SEC2 driver code
+ * (a planned Win32 API driver never happened) so this change
+ * should be transparent to users.
+ */
+#define H5FD_windows_init H5FD_sec2_init
+#define H5FD_windows_term H5FD_sec2_term
H5_DLL herr_t H5Pset_fapl_windows(hid_t fapl_id);
#ifdef __cplusplus