summaryrefslogtreecommitdiffstats
path: root/src/H5FDstdio.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5FDstdio.c')
-rw-r--r--src/H5FDstdio.c58
1 files changed, 40 insertions, 18 deletions
diff --git a/src/H5FDstdio.c b/src/H5FDstdio.c
index 6dbc515..9b1dbf9 100644
--- a/src/H5FDstdio.c
+++ b/src/H5FDstdio.c
@@ -368,26 +368,35 @@ H5FD_stdio_open( const char *name, unsigned flags, hid_t fapl_id,
if (ADDR_OVERFLOW(maxaddr))
H5Epush_ret(func, H5E_ERR_CLS, H5E_ARGS, H5E_OVERFLOW, "maxaddr too large", NULL)
- /* Attempt to open/create the file */
- if (access(name, F_OK) < 0) {
- if ((flags & H5F_ACC_CREAT) && (flags & H5F_ACC_RDWR)) {
+ /* Tentatively open file in read-only mode, to check for existence */
+ if(flags & H5F_ACC_RDWR)
+ f = fopen(name, "rb+");
+ else
+ f = fopen(name, "rb");
+
+ if(!f) {
+ /* File doesn't exist */
+ if(flags & H5F_ACC_CREAT) {
+ assert(flags & H5F_ACC_RDWR);
f = fopen(name, "wb+");
write_access = 1; /* Note the write access */
}
else
H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_CANTOPENFILE, "file doesn't exist and CREAT wasn't specified", NULL)
- } else if ((flags & H5F_ACC_CREAT) && (flags & H5F_ACC_EXCL)) {
+ } else if(flags & H5F_ACC_EXCL) {
+ /* File exists, but EXCL is passed. Fail. */
+ assert(flags & H5F_ACC_CREAT);
+ fclose(f);
H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_FILEEXISTS, "file exists but CREAT and EXCL were specified", NULL)
- } else if (flags & H5F_ACC_RDWR) {
- if (flags & H5F_ACC_TRUNC)
- f = fopen(name, "wb+");
- else
- f = fopen(name, "rb+");
+ } else if(flags & H5F_ACC_RDWR) {
+ if(flags & H5F_ACC_TRUNC)
+ f = freopen(name, "wb+", f);
write_access = 1; /* Note the write access */
- } else {
- f = fopen(name, "rb");
- }
- if (!f)
+ } /* end if */
+ /* Note there is no need to reopen if neither TRUNC nor EXCL are specified,
+ * as the tentative open will work */
+
+ if(!f)
H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_CANTOPENFILE, "fopen failed", NULL)
/* Build the return value */
@@ -409,23 +418,36 @@ H5FD_stdio_open( const char *name, unsigned flags, hid_t fapl_id,
/* Get the file descriptor (needed for truncate and some Windows information) */
file->fd = fileno(file->fp);
- if(file->fd < 0)
+ if(file->fd < 0) {
+ free(file);
+ fclose(f);
H5Epush_ret(func, H5E_ERR_CLS, H5E_FILE, H5E_CANTOPENFILE, "unable to get file descriptor", NULL);
+ } /* end if */
#ifdef H5_HAVE_WIN32_API
file->hFile = (HANDLE)_get_osfhandle(file->fd);
- if(INVALID_HANDLE_VALUE == file->hFile)
+ if(INVALID_HANDLE_VALUE == file->hFile) {
+ free(file);
+ fclose(f);
H5Epush_ret(func, H5E_ERR_CLS, H5E_FILE, H5E_CANTOPENFILE, "unable to get Windows file handle", NULL);
+ } /* end if */
- if(!GetFileInformationByHandle((HANDLE)file->hFile, &fileinfo))
- H5Epush_ret(func, H5E_ERR_CLS, H5E_FILE, H5E_CANTOPENFILE, "unable to get Windows file desinformationcriptor", NULL);
+ if(!GetFileInformationByHandle((HANDLE)file->hFile, &fileinfo)) {
+ free(file);
+ fclose(f);
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_FILE, H5E_CANTOPENFILE, "unable to get Windows file descriptor information", NULL);
+ } /* end if */
file->nFileIndexHigh = fileinfo.nFileIndexHigh;
file->nFileIndexLow = fileinfo.nFileIndexLow;
file->dwVolumeSerialNumber = fileinfo.dwVolumeSerialNumber;
#else /* H5_HAVE_WIN32_API */
- fstat(file->fd, &sb);
+ if(fstat(file->fd, &sb) < 0) {
+ free(file);
+ fclose(f);
+ H5Epush_ret(func, H5E_ERR_CLS, H5E_FILE, H5E_BADFILE, "unable to fstat file", NULL)
+ } /* end if */
file->device = sb.st_dev;
#ifdef H5_VMS
file->inode[0] = sb.st_ino[0];