diff options
author | Robb Matzke <matzke@llnl.gov> | 1998-02-19 18:19:48 (GMT) |
---|---|---|
committer | Robb Matzke <matzke@llnl.gov> | 1998-02-19 18:19:48 (GMT) |
commit | b24130dcf051e6f569612c0a9b13d2168c6213c0 (patch) | |
tree | 607e5fc4db5da70f6584c9567f28ef9b88faeae1 /src/H5Fstdio.c | |
parent | 5b8d25d3c6db32d04213978500dca99dd1794d77 (diff) | |
download | hdf5-b24130dcf051e6f569612c0a9b13d2168c6213c0.zip hdf5-b24130dcf051e6f569612c0a9b13d2168c6213c0.tar.gz hdf5-b24130dcf051e6f569612c0a9b13d2168c6213c0.tar.bz2 |
[svn-r290] Changes since 19980206
----------------------
./configure.in
./src/H5Fprivate.h
./src/H5Fsec2.c
We now detect and use lseek64() on systems that have it (e.g.,
Irix64) and are able to generate >2GB files on Irix XFS file
systems (and anything else that supports large files). This
change also removed some warning messages from the Irix `-64'
compiler.
> $ ls -l istore.h5
> -rw-r--r-- 1 matzke meshtv 8605436856 Feb 17 14:03 istore.h5
./configure.in
./src/H5Fprivate.h
./src/H5Fstdio.h
We now detect and use fseek64() on systems that have it (e.g.,
Irix64) and are able to generate >2GB files on Irix XFS file
systems (and anything else that supports large files). This
change also removed some warning messages from the Iris `-64'
compiler.
./src/H5E.c
./src/H5Epublic.h
Added the H5E_OVERFLOW error to signal file address overflow.
./src/H5Fpublic.h
./examples/h5_chunk_read.c
./examples/h5_compound.c
./examples/h5_extend_write.c
./examples/h5_group.c
./examples/h5_read.c
./examples/h5_write.c
./html/Datasets.html
./html/Files.html
./html/H5.api.html
./html/H5.intro.html
./html/H5.sample_code.html
./html/ph5example.c
./html/review1.html
./test/cmpd_dset.c
./test/dsets.c
./test/extend.c
./test/tfile.c
./test/th5p.c
./test/theap.c
./test/tohdr.c
./test/tstab.c
./testpar/phdf5.c
Renamed file access constants to follow the naming scheme.
Also changed the base names a little to be more accurate as to
what they do. The old names H5ACC_WRITE and H5ACC_OVERWRITE
will temporarily work.
H5ACC_DEFAULT --> H5F_ACC_RDONLY for H5Fopen()
H5ACC_DEFAULT --> H5F_ACC_EXCL for H5Fcreate()
H5ACC_WRITE --> H5F_ACC_RDWR
H5ACC_OVERWRITE --> H5F_ACC_TRUNC
Albert or Kim: The H5ACC_INDEPENDENT and H5ACC_COLLECTIVE
macros in H5Fpublic.h should be an enum typedef and have names
more like H5F_MPIO_INDEPENDENT and H5F_MPIO_COLLECTIVE. Also
change the access_mode argument of H5Cset_mpio().
H5Fcreate() and H5Fopen() are more strict now about which
flags are acceptable for the operation.
./src/H5Fprivate.h
./src/H5F.c
./src/H5C.c
Changed the file access template to make it more general. A
union contains a struct for each type of low-level driver and
the default template is initialized at run-time.
./src/H5Fpublic.h
./src/H5F.c
Added H5Fget_access_template() and cleaned up
H5Fget_create_template().
./src/H5C.c
The H5Cset_mpi() no longer trashes the file access template
when an error is detected. We check for errors and *then*
update the file access template.
Added H5C_close() so Albert and Kim have a place to release
the MPI communicator and info from the file access property
list.
Kim or Albert: I notice in H5Cset_mpi() you copy the MPI
communicator. Do you need to do something similar in
H5C_copy()?
./src/H5F.c
Added more error checking for the file creation and access
property lists because it used to be possible to make the
library dump core by swapping the creation and access property
list ID numbers of H5Fcreate().
./test/istore.c
./test/tfile.c
./test/th5p.c
./test/theap.c
./test/tohdr.c
./test/tstab.c
./testpar/testphdf5.c
One must pass H5C_DEFAULT as the file creation or access
property list in order to get the default property list. It
is no longer possible to pass zero or any other arbitrary bad
object ID.
./src/H5Fcore.c
./src/H5Ffamly.c
./src/H5Flow.c
./src/H5Fmpio.c
./src/H5Fsec2.c
./src/H5Fsplit.c
./src/H5Fstdio.c
./src/H5MF.c
The file access property list is passed to all H5F_low_...()
functions and to the drivers.
./src/H5Fcore.c
The block size can be set at run time on a per-file basis
instead of at compile time across all files. The "5000 items in
a group test" now takes 1.6 seconds.
./src/H5private.h
Removed inclusion of mpi.h and mpio.h since they're included
from H5public.h.
./src/H5Cpublic.h
./src/H5C.c
Added H5Cset_stdio(), H5Cset_sec2(), H5Cset_core(),
H5Cset_split(), and H5Cset_family() in addition to the
H5Cset_mpio() that Kim and Albert already wrote. We still
need the H5Cget_driver() and an H5Cget...() counterpart for
each of those functions. The split and family drivers still
need a little work but I'm checking this in anyway.
Diffstat (limited to 'src/H5Fstdio.c')
-rw-r--r-- | src/H5Fstdio.c | 315 |
1 files changed, 177 insertions, 138 deletions
diff --git a/src/H5Fstdio.c b/src/H5Fstdio.c index a7cb096..ed0cdb2 100644 --- a/src/H5Fstdio.c +++ b/src/H5Fstdio.c @@ -1,9 +1,9 @@ /* * Copyright (C) 1997 NCSA - * All rights reserved. + * All rights reserved. * * Programmer: Robb Matzke <matzke@llnl.gov> - * Wednesday, October 22, 1997 + * Wednesday, October 22, 1997 * * Purpose: This is the Posix stdio.h I/O subclass of H5Flow. */ @@ -16,89 +16,92 @@ #include <sys/types.h> #include <sys/stat.h> -#define PABLO_MASK H5F_stdio -static hbool_t interface_initialize_g = FALSE; -#define INTERFACE_INIT NULL +#define PABLO_MASK H5F_stdio +static hbool_t interface_initialize_g = FALSE; +#define INTERFACE_INIT NULL -static H5F_low_t *H5F_stdio_open(const char *name, uintn flags, - H5F_search_t *key); -static herr_t H5F_stdio_close(H5F_low_t *lf); -static herr_t H5F_stdio_read(H5F_low_t *lf, const haddr_t *addr, size_t size, - uint8 *buf); -static herr_t H5F_stdio_write(H5F_low_t *lf, const haddr_t *addr, size_t size, - const uint8 *buf); -static herr_t H5F_stdio_flush(H5F_low_t *lf); +static H5F_low_t *H5F_stdio_open(const char *name, + const H5F_access_t *access_parms, uintn flags, + H5F_search_t *key/*out*/); +static herr_t H5F_stdio_close(H5F_low_t *lf, const H5F_access_t *access_parms); +static herr_t H5F_stdio_read(H5F_low_t *lf, const H5F_access_t *access_parms, + const haddr_t *addr, size_t size, + uint8 *buf/*out*/); +static herr_t H5F_stdio_write(H5F_low_t *lf, const H5F_access_t *access_parms, + const haddr_t *addr, size_t size, + const uint8 *buf); +static herr_t H5F_stdio_flush(H5F_low_t *lf, const H5F_access_t *access_parms); + +const H5F_low_class_t H5F_LOW_STDIO_g[1] = {{ + NULL, /* use default access(2) func */ + H5F_stdio_open, /* open method */ + H5F_stdio_close, /* close method */ + H5F_stdio_read, /* read method */ + H5F_stdio_write, /* write method */ + H5F_stdio_flush, /* flush method */ + NULL, /* extend method */ +}}; -const H5F_low_class_t H5F_LOW_STDIO[1] = -{ - { - NULL, /* use default access(2) func */ - H5F_stdio_open, /* open method */ - H5F_stdio_close, /* close method */ - H5F_stdio_read, /* read method */ - H5F_stdio_write, /* write method */ - H5F_stdio_flush, /* flush method */ - NULL, /* extend method */ - }}; /*------------------------------------------------------------------------- - * Function: H5F_stdio_open + * Function: H5F_stdio_open * - * Purpose: Opens a file with name NAME. The FLAGS are a bit field with - * the possible values defined in H5F_low_open(). + * Purpose: Opens a file with name NAME. The FLAGS are a bit field with + * the possible values defined in H5F_low_open(). * - * Bugs: H5F_ACC_EXCL has a race condition. + * Bugs: H5F_ACC_EXCL has a race condition. * * Errors: - * IO CANTOPENFILE File doesn't exist and CREAT wasn't - * specified. - * IO CANTOPENFILE Fopen failed. - * IO FILEEXISTS File exists but CREAT and EXCL were - * specified. + * IO CANTOPENFILE File doesn't exist and CREAT wasn't + * specified. + * IO CANTOPENFILE Fopen failed. + * IO FILEEXISTS File exists but CREAT and EXCL were + * specified. * - * Return: Success: Low-level file pointer + * Return: Success: Low-level file pointer * - * Failure: NULL + * Failure: NULL * - * Programmer: Robb Matzke - * Wednesday, October 22, 1997 + * Programmer: Robb Matzke + * Wednesday, October 22, 1997 * * Modifications: * *------------------------------------------------------------------------- */ -static H5F_low_t * -H5F_stdio_open(const char *name, uintn flags, H5F_search_t *key /*out */ ) +static H5F_low_t * +H5F_stdio_open(const char *name, const H5F_access_t *access_parms, + uintn flags, H5F_search_t *key/*out*/) { - H5F_low_t *lf = NULL; - FILE *f = NULL; - struct stat sb; + H5F_low_t *lf = NULL; + FILE *f = NULL; + struct stat sb; FUNC_ENTER(H5F_stdio_open, NULL); if (access(name, F_OK) < 0) { - if ((flags & H5F_ACC_CREAT) && (flags & H5F_ACC_WRITE)) { - f = fopen(name, "wb+"); - } else { - HRETURN_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL, - "file doesn't exist and CREAT wasn't specified"); - } + if ((flags & H5F_ACC_CREAT) && (flags & H5F_ACC_RDWR)) { + f = fopen(name, "wb+"); + } else { + HRETURN_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL, + "file doesn't exist and CREAT wasn't specified"); + } } else if ((flags & H5F_ACC_CREAT) && (flags & H5F_ACC_EXCL)) { - HRETURN_ERROR(H5E_IO, H5E_FILEEXISTS, NULL, - "file exists but CREAT and EXCL were specified"); + HRETURN_ERROR(H5E_IO, H5E_FILEEXISTS, NULL, + "file exists but CREAT and EXCL were specified"); - } else if (flags & H5F_ACC_WRITE) { - 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 = fopen(name, "wb+"); + else + f = fopen(name, "rb+"); } else { - f = fopen(name, "rb"); + f = fopen(name, "rb"); } if (!f) - HRETURN_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL, "fopen failed"); + HRETURN_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL, "fopen failed"); /* Build the return value */ lf = H5MM_xcalloc(1, sizeof(H5F_low_t)); @@ -107,46 +110,46 @@ H5F_stdio_open(const char *name, uintn flags, H5F_search_t *key /*out */ ) lf->u.stdio.cur = 0; H5F_addr_reset(&(lf->eof)); if (fseek(lf->u.stdio.f, 0, SEEK_END) < 0) { - lf->u.stdio.op = H5F_OP_UNKNOWN; + lf->u.stdio.op = H5F_OP_UNKNOWN; } else { - H5F_addr_inc(&(lf->eof), ftell(lf->u.stdio.f)); + H5F_addr_inc(&(lf->eof), ftell(lf->u.stdio.f)); } /* The unique key */ if (key) { - fstat(fileno(f), &sb); - key->dev = sb.st_dev; - key->ino = sb.st_ino; + fstat(fileno(f), &sb); + key->dev = sb.st_dev; + key->ino = sb.st_ino; } FUNC_LEAVE(lf); } /*------------------------------------------------------------------------- - * Function: H5F_stdio_close + * Function: H5F_stdio_close * - * Purpose: Closes a file. + * Purpose: Closes a file. * * Errors: - * IO CLOSEERROR Fclose failed. + * IO CLOSEERROR Fclose failed. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Wednesday, October 22, 1997 + * Programmer: Robb Matzke + * Wednesday, October 22, 1997 * * Modifications: * *------------------------------------------------------------------------- */ static herr_t -H5F_stdio_close(H5F_low_t *lf) +H5F_stdio_close(H5F_low_t *lf, const H5F_access_t *access_parms) { FUNC_ENTER(H5F_stdio_close, FAIL); if (fclose(lf->u.stdio.f) < 0) { - HRETURN_ERROR(H5E_IO, H5E_CLOSEERROR, FAIL, "fclose failed"); + HRETURN_ERROR(H5E_IO, H5E_CLOSEERROR, FAIL, "fclose failed"); } lf->u.stdio.f = NULL; @@ -154,66 +157,82 @@ H5F_stdio_close(H5F_low_t *lf) } /*------------------------------------------------------------------------- - * Function: H5F_stdio_read + * Function: H5F_stdio_read * - * Purpose: Reads SIZE bytes beginning at address ADDR in file LF and - * places them in buffer BUF. Reading past the logical or - * physical end of file returns zeros instead of failing. + * Purpose: Reads SIZE bytes beginning at address ADDR in file LF and + * places them in buffer BUF. Reading past the logical or + * physical end of file returns zeros instead of failing. * * Errors: - * IO READERROR Fread failed. - * IO SEEKERROR Fseek failed. + * IO READERROR Fread failed. + * IO SEEKERROR Fseek failed. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Wednesday, October 22, 1997 + * Programmer: Robb Matzke + * Wednesday, October 22, 1997 * * Modifications: * *------------------------------------------------------------------------- */ static herr_t -H5F_stdio_read(H5F_low_t *lf, const haddr_t *addr, size_t size, uint8 *buf) +H5F_stdio_read(H5F_low_t *lf, const H5F_access_t *access_parms, + const haddr_t *addr, size_t size, uint8 *buf/*out*/) { - size_t n; - off_t offset; + size_t n; + uint64 mask; +#ifdef HAVE_FSEEK64 + long long offset; +#else + off_t offset; +#endif FUNC_ENTER(H5F_stdio_read, FAIL); /* Check for overflow */ - offset = addr->offset; /*FIX_ME*/ - assert("address overflowed" && offset == addr->offset); - assert("overflow" && offset + size >= offset); + mask = (uint64)1 << (8*sizeof(offset)-1); + if (addr->offset >= mask || + addr->offset + size < addr->offset || + addr->offset+size >= mask) { + HRETURN_ERROR (H5E_IO, H5E_OVERFLOW, FAIL, "file address overflowed"); + } +#ifdef HAVE_FSEEK64 + offset = (long long)(addr->offset); /*checked for overflow*/ +#else + offset = (off_t)(addr->offset); /*checked for overflow*/ +#endif /* Check easy cases */ - if (0 == size) - HRETURN(SUCCEED); + if (0 == size) HRETURN(SUCCEED); if (offset >= lf->eof.offset) { - HDmemset(buf, 0, size); - HRETURN(SUCCEED); + HDmemset(buf, 0, size); + HRETURN(SUCCEED); } + /* * Seek to the correct file position. */ if (!H5F_OPT_SEEK || - lf->u.stdio.op != H5F_OP_READ || - lf->u.stdio.cur != offset) { - if (fseek(lf->u.stdio.f, offset, SEEK_SET) < 0) { - HRETURN_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "fseek failed"); - } - lf->u.stdio.cur = offset; + lf->u.stdio.op != H5F_OP_READ || + lf->u.stdio.cur != offset) { + if (fseek(lf->u.stdio.f, offset, SEEK_SET) < 0) { + HRETURN_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "fseek failed"); + } + lf->u.stdio.cur = offset; } + /* * Read zeros past the logical end of file (physical is handled below) */ if ((size_t) offset + size > lf->eof.offset) { - size_t nbytes = (size_t) offset + size - lf->eof.offset; - HDmemset(buf + size - nbytes, 0, nbytes); - size -= nbytes; + size_t nbytes = (size_t) offset + size - lf->eof.offset; + HDmemset(buf + size - nbytes, 0, nbytes); + size -= nbytes; } + /* * Read the data. Since we're reading single-byte values, a partial read * will advance the file position by N. If N is negative or an error @@ -221,102 +240,122 @@ H5F_stdio_read(H5F_low_t *lf, const haddr_t *addr, size_t size, uint8 *buf) */ n = fread(buf, 1, size, lf->u.stdio.f); if (n <= 0 && ferror(lf->u.stdio.f)) { - lf->u.stdio.op = H5F_OP_UNKNOWN; - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "fread failed"); + lf->u.stdio.op = H5F_OP_UNKNOWN; + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "fread failed"); } else if (n < size) { - HDmemset(buf + n, 0, size - n); + HDmemset(buf + n, 0, size - n); } + /* * Update the file position data. */ lf->u.stdio.op = H5F_OP_READ; - lf->u.stdio.cur = offset + n; /*FIX_ME*/ + lf->u.stdio.cur = offset + n; FUNC_LEAVE(SUCCEED); } + /*------------------------------------------------------------------------- - * Function: H5F_stdio_write + * Function: H5F_stdio_write * - * Purpose: Writes SIZE bytes from the beginning of BUF into file LF at - * file address ADDR. + * Purpose: Writes SIZE bytes from the beginning of BUF into file LF at + * file address ADDR. * * Errors: - * IO SEEKERROR Fseek failed. - * IO WRITEERROR Fwrite failed. + * IO SEEKERROR Fseek failed. + * IO WRITEERROR Fwrite failed. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Wednesday, October 22, 1997 + * Programmer: Robb Matzke + * Wednesday, October 22, 1997 * * Modifications: * *------------------------------------------------------------------------- */ static herr_t -H5F_stdio_write(H5F_low_t *lf, const haddr_t *addr, size_t size, - const uint8 *buf) +H5F_stdio_write(H5F_low_t *lf, const H5F_access_t *access_parms, + const haddr_t *addr, size_t size, + const uint8 *buf) { - off_t offset; + ssize_t n; + uint64 mask; +#ifdef HAVE_FSEEK64 + long long offset; +#else + off_t offset; +#endif FUNC_ENTER(H5F_stdio_write, FAIL); /* Check for overflow */ - offset = addr->offset; /*FIX_ME*/ - assert("address overflowed" && offset == addr->offset); - assert("overflow" && offset + size >= offset); + mask = (uint64)1 << (8*sizeof(offset)-1); + if (addr->offset >= mask || + addr->offset+size < addr->offset || + addr->offset+size >= mask) { + HRETURN_ERROR (H5E_IO, H5E_OVERFLOW, FAIL, "file address overflowed"); + } +#ifdef HAVE_FSEEK64 + offset = (long long)(addr->offset); /*checked for overflow*/ + n = (long long)size; /*checked for overflow*/ +#else + offset = (long)(addr->offset); /*checked for overflow*/ + n = (off_t)size; /*checked for overflow*/ +#endif /* * Seek to the correct file position. */ if (!H5F_OPT_SEEK || - lf->u.stdio.op != H5F_OP_WRITE || - lf->u.stdio.cur != offset) { - if (fseek(lf->u.stdio.f, offset, SEEK_SET) < 0) { - HRETURN_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "fseek failed"); - } - lf->u.stdio.cur = offset; + lf->u.stdio.op != H5F_OP_WRITE || + lf->u.stdio.cur != offset) { + if (fseek(lf->u.stdio.f, offset, SEEK_SET) < 0) { + HRETURN_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "fseek failed"); + } + lf->u.stdio.cur = offset; } /* * Write the buffer. On successful return, the file position will be * advanced by the number of bytes read. Otherwise nobody knows where it * is. */ - if (size != fwrite(buf, 1, size, lf->u.stdio.f)) { - lf->u.stdio.op = H5F_OP_UNKNOWN; - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "fwrite failed"); + if (n != fwrite(buf, 1, size, lf->u.stdio.f)) { + lf->u.stdio.op = H5F_OP_UNKNOWN; + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "fwrite failed"); } /* * Update seek optimizing data. */ lf->u.stdio.op = H5F_OP_WRITE; - lf->u.stdio.cur = offset + size; /*FIX_ME*/ + lf->u.stdio.cur = offset + n; FUNC_LEAVE(SUCCEED); } + /*------------------------------------------------------------------------- - * Function: H5F_stdio_flush + * Function: H5F_stdio_flush * - * Purpose: Makes sure that all data is on disk. + * Purpose: Makes sure that all data is on disk. * * Errors: - * IO WRITEERROR Fflush failed. + * IO WRITEERROR Fflush failed. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Wednesday, October 22, 1997 + * Programmer: Robb Matzke + * Wednesday, October 22, 1997 * * Modifications: * *------------------------------------------------------------------------- */ static herr_t -H5F_stdio_flush(H5F_low_t *lf) +H5F_stdio_flush(H5F_low_t *lf, const H5F_access_t *access_parms) { FUNC_ENTER(H5F_stdio_flush, FAIL); @@ -330,7 +369,7 @@ H5F_stdio_flush(H5F_low_t *lf) * Flush */ if (fflush(lf->u.stdio.f) < 0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "fflush failed"); + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "fflush failed"); } FUNC_LEAVE(SUCCEED); } |