diff options
-rw-r--r-- | CMakeLists.txt | 10 | ||||
-rw-r--r-- | config/cmake/ConfigureChecks.cmake | 3 | ||||
-rw-r--r-- | config/cmake/H5pubconf.h.in | 7 | ||||
-rw-r--r-- | src/H5FDlog.c | 627 | ||||
-rw-r--r-- | src/H5FDsec2.c | 605 | ||||
-rw-r--r-- | src/H5FDwindows.c | 1053 | ||||
-rw-r--r-- | src/H5FDwindows.h | 11 |
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
|