diff --git a/libsrc/posixio.c b/libsrc/posixio.c index 0654fef9d..0b45686f0 100644 --- a/libsrc/posixio.c +++ b/libsrc/posixio.c @@ -223,7 +223,7 @@ fgrow2(const int fd, const off_t len) posp - pointer to current position in file, updated after write. */ static int -px_pgout(ncio *const nciop, +px_pgout(ncio *const nciop, off_t const offset, const size_t extent, void *const vp, off_t *posp) { @@ -254,7 +254,7 @@ px_pgout(ncio *const nciop, while((partial = write(nciop->fd, nvp, nextent)) != -1) { if(partial == nextent) break; - nvp += partial; + nvp += partial; nextent -= partial; } if(partial == -1) @@ -264,14 +264,16 @@ px_pgout(ncio *const nciop, return ENOERR; } -/* Read in a page of data. +/*! Read in a page of data. - nciop - a pointer to the ncio struct for this file. - offset - byte offset in file where read starts. - extent - the size of the page that will be read. - vp - a pointer to where the data will end up. - nreadp - returned number of bytes actually read (may be less than extent). - posp - pointer to current position in file, updated after read. + @param[in] nciop A pointer to the ncio struct for this file. + @param[in] offset The byte offset in file where read starts. + @param[in] extent The size of the page that will be read. + @param[in] vp A pointer to where the data will end up. + + @param[in,out] nreadp Returned number of bytes actually read (may be less than extent). + @param[in,out] posp The pointer to current position in file, updated after read. + @return Return 0 on success, otherwise an error code. */ static int px_pgin(ncio *const nciop, @@ -285,8 +287,18 @@ px_pgin(ncio *const nciop, assert(offset % X_ALIGN == 0); assert(extent % X_ALIGN == 0); #endif - + /* assert(*posp == OFF_NONE || *posp == lseek(nciop->fd, 0, SEEK_CUR)); + */ + /* *posp == OFF_NONE (-1) on first call. This + is problematic because lseek also returns -1 + on error. Use errno instead. */ + if(*posp != OFF_NONE || *posp == lseek(nciop->fd, 0, SEEK_CUR)) { + if(errno) { + status = errno; + return status; + } + } if(*posp != offset) { @@ -333,7 +345,7 @@ typedef struct ncio_px { size_t blksz; off_t pos; /* buffer */ - off_t bf_offset; + off_t bf_offset; size_t bf_extent; size_t bf_cnt; void *bf_base; @@ -406,7 +418,7 @@ ncio_px_rel(ncio *const nciop, off_t offset, int rflags) /* POSIX get. This will "make a region available." Since we're using buffered IO, this means that if needed, we'll fetch a new page from the file, otherwise, just return a pointer to what's in memory - already. + already. nciop - pointer to ncio struct, containing file info. pxp - pointer to ncio_px struct, which contains special metadate @@ -416,7 +428,7 @@ ncio_px_rel(ncio *const nciop, off_t offset, int rflags) rflags - One of the RGN_* flags defined in ncio.h. vpp - pointer to pointer that will recieve data. - NOTES: + NOTES: * For blkoffset round offset down to the nearest pxp->blksz. This provides the offset (in bytes) to the beginning of the block that @@ -436,7 +448,7 @@ ncio_px_rel(ncio *const nciop, off_t offset, int rflags) * If this is called on a newly opened file, pxp->bf_offset will be OFF_NONE and we'll jump to label pgin to immediately read in a - page. + page. */ static int px_get(ncio *const nciop, ncio_px *const pxp, @@ -449,7 +461,7 @@ px_get(ncio *const nciop, ncio_px *const pxp, const off_t blkoffset = _RNDDOWN(offset, (off_t)pxp->blksz); off_t diff = (size_t)(offset - blkoffset); off_t blkextent = _RNDUP(diff + extent, pxp->blksz); - + assert(extent != 0); assert(extent < X_INT_MAX); /* sanity check */ assert(offset >= 0); /* sanity check */ @@ -475,7 +487,7 @@ px_get(ncio *const nciop, ncio_px *const pxp, if(blkoffset == pxp->bf_offset) { /* hit */ - if(blkextent > pxp->bf_extent) + if(blkextent > pxp->bf_extent) { /* page in upper */ void *const middle = @@ -669,7 +681,7 @@ done: corresponding call to rel(). For POSIX systems, without NC_SHARE. This function gets a page of - size extent? + size extent? This is a wrapper for the function px_get, which does all the heavy lifting. @@ -682,13 +694,13 @@ done: vpp - handle to point at data when it's been read. */ static int -ncio_px_get(ncio *const nciop, +ncio_px_get(ncio *const nciop, off_t offset, size_t extent, int rflags, void **const vpp) { ncio_px *const pxp = (ncio_px *)nciop->pvt; - + if(fIsSet(rflags, RGN_WRITE) && !fIsSet(nciop->ioflags, NC_WRITE)) return EPERM; /* attempt to write readonly file */ @@ -718,7 +730,7 @@ px_double_buffer(ncio *const nciop, off_t to, off_t from, int status = ENOERR; void *src; void *dest; - + #if INSTRUMENT fprintf(stderr, "\tdouble_buffr %ld %ld %ld\n", (long)to, (long)from, (long)nbytes); @@ -736,7 +748,7 @@ fprintf(stderr, "\tdouble_buffr %ld %ld %ld\n", pxp->slave->blksz = pxp->blksz; /* pos done below */ - pxp->slave->bf_offset = pxp->bf_offset; + pxp->slave->bf_offset = pxp->bf_offset; pxp->slave->bf_extent = pxp->bf_extent; pxp->slave->bf_cnt = pxp->bf_cnt; pxp->slave->bf_base = malloc(2 * pxp->blksz); @@ -748,7 +760,7 @@ fprintf(stderr, "\tdouble_buffr %ld %ld %ld\n", pxp->slave->bf_refcount = 0; pxp->slave->slave = NULL; } - + pxp->slave->pos = pxp->pos; status = px_get(nciop, pxp->slave, from, nbytes, 0, &src); @@ -764,7 +776,7 @@ fprintf(stderr, "\tdouble_buffr %ld %ld %ld\n", (void)px_rel(pxp->slave, from, 0); (void)px_rel(pxp, to, RGN_MODIFIED); - + return status; } @@ -788,7 +800,7 @@ ncio_px_move(ncio *const nciop, off_t to, off_t from, { ncio_px *const pxp = (ncio_px *)nciop->pvt; int status = ENOERR; - off_t lower; + off_t lower; off_t upper; char *base; size_t diff; @@ -796,7 +808,7 @@ ncio_px_move(ncio *const nciop, off_t to, off_t from, if(to == from) return ENOERR; /* NOOP */ - + if(fIsSet(rflags, RGN_WRITE) && !fIsSet(nciop->ioflags, NC_WRITE)) return EPERM; /* attempt to write readonly file */ @@ -805,7 +817,7 @@ ncio_px_move(ncio *const nciop, off_t to, off_t from, if(to > from) { /* growing */ - lower = from; + lower = from; upper = to; } else @@ -865,7 +877,7 @@ else } return ENOERR; } - + #if INSTRUMENT fprintf(stderr, "\tncio_px_move small\n"); #endif @@ -876,10 +888,10 @@ fprintf(stderr, "\tncio_px_move small\n"); return status; if(to > from) - (void) memmove(base + diff, base, nbytes); + (void) memmove(base + diff, base, nbytes); else - (void) memmove(base, base + diff, nbytes); - + (void) memmove(base, base + diff, nbytes); + (void) px_rel(pxp, lower, RGN_MODIFIED); return status; @@ -938,7 +950,7 @@ ncio_px_freepvt(void *const pvt) free(pxp->slave); pxp->slave = NULL; } - + if(pxp->bf_base != NULL) { free(pxp->bf_base); @@ -1036,7 +1048,7 @@ ncio_px_init(ncio *const nciop) typedef struct ncio_spx { off_t pos; /* buffer */ - off_t bf_offset; + off_t bf_offset; size_t bf_extent; size_t bf_cnt; void *bf_base; @@ -1117,7 +1129,7 @@ ncio_spx_get(ncio *const nciop, #ifdef X_ALIGN size_t rem; #endif - + if(fIsSet(rflags, RGN_WRITE) && !fIsSet(nciop->ioflags, NC_WRITE)) return EPERM; /* attempt to write readonly file */ @@ -1191,7 +1203,7 @@ strategy(ncio *const nciop, off_t to, off_t offset, #ifdef X_ALIGN size_t rem; #endif - + assert(extent != 0); assert(extent < X_INT_MAX); /* sanity check */ #if INSTRUMENT @@ -1241,7 +1253,7 @@ fprintf(stderr, "strategy %ld at %ld to %ld\n", return status; pxp->bf_offset = to; /* TODO: XALIGN */ - + if(pxp->bf_cnt < extent) pxp->bf_cnt = extent; @@ -1271,7 +1283,7 @@ ncio_spx_move(ncio *const nciop, off_t to, off_t from, size_t nbytes, int rflags) { int status = ENOERR; - off_t lower = from; + off_t lower = from; off_t upper = to; char *base; size_t diff; @@ -1281,11 +1293,11 @@ ncio_spx_move(ncio *const nciop, off_t to, off_t from, if(to == from) return ENOERR; /* NOOP */ - + if(to > from) { /* growing */ - lower = from; + lower = from; upper = to; } else @@ -1305,10 +1317,10 @@ ncio_spx_move(ncio *const nciop, off_t to, off_t from, return status; if(to > from) - (void) memmove(base + diff, base, nbytes); + (void) memmove(base + diff, base, nbytes); else - (void) memmove(base, base + diff, nbytes); - + (void) memmove(base, base + diff, nbytes); + (void) ncio_spx_rel(nciop, lower, RGN_MODIFIED); return status; @@ -1344,12 +1356,12 @@ ncio_spx_freepvt(void *const pvt) /* This does the second half of the ncio_spx struct initialization for - POSIX systems, with NC_SHARE on. + POSIX systems, with NC_SHARE on. nciop - pointer to ncio struct for this file. File has been opened. sizehintp - pointer to a size which will be rounded up to the nearest 8-byt boundary and then used as the max size "chunk" (or - page) to read from the file. + page) to read from the file. */ static int ncio_spx_init2(ncio *const nciop, const size_t *const sizehintp) @@ -1439,7 +1451,7 @@ ncio_px_new(const char *path, int ioflags) size_t sz_path = M_RNDUP(strlen(path) +1); size_t sz_ncio_pvt; ncio *nciop; - + #if ALWAYS_NC_SHARE /* DEBUG */ fSet(ioflags, NC_SHARE); #endif @@ -1452,7 +1464,7 @@ ncio_px_new(const char *path, int ioflags) nciop = (ncio *) malloc(sz_ncio + sz_path + sz_ncio_pvt); if(nciop == NULL) return NULL; - + nciop->ioflags = ioflags; *((int *)&nciop->fd) = -1; /* cast away const */ @@ -1494,8 +1506,8 @@ ncio_px_new(const char *path, int ioflags) ioflags - flags from nc_create initialsz - From the netcdf man page: "The argument Iinitialsize sets the initial size of the file at creation time." - igeto - - igetsz - + igeto - + igetsz - sizehintp - this eventually goes into pxp->blksz and is the size of a page of data for buffered reads and writes. nciopp - pointer to a pointer that will get location of newly @@ -1608,17 +1620,17 @@ unwind_new: path - path of data file. ioflags - flags passed into nc_open. - + igeto - looks like this function can do an initial page get, and igeto is going to be the offset for that. But it appears to be - unused + unused igetsz - the size in bytes of initial page get (a.k.a. extent). Not ever used in the library. - + sizehintp - pointer to sizehint parameter from nc__open or - nc__create. This is used to set pxp->blksz. - + nc__create. This is used to set pxp->blksz. + Here's what the man page has to say: "The argument referenced by chunksize controls a space versus time @@ -1724,7 +1736,7 @@ unwind_new: return status; } -/* +/* * Get file size in bytes. */ static int @@ -1733,7 +1745,7 @@ ncio_px_filesize(ncio *nciop, off_t *filesizep) /* There is a problem with fstat on Windows based systems - which manifests (so far) when Config RELEASE is built. + which manifests (so far) when Config RELEASE is built. Use _filelengthi64 isntead. */ #ifdef HAVE_FILE_LENGTH_I64 @@ -1766,7 +1778,7 @@ ncio_px_pad_length(ncio *nciop, off_t length) { int status = ENOERR; - + if(nciop == NULL) return EINVAL; @@ -1789,12 +1801,12 @@ ncio_px_pad_length(ncio *nciop, off_t length) Sync any changes, then close the open file associated with the ncio struct, and free its memory. - + nciop - pointer to ncio to close. doUnlink - if true, unlink file */ -static int +static int ncio_px_close(ncio *nciop, int doUnlink) { int status = ENOERR; @@ -1803,14 +1815,14 @@ ncio_px_close(ncio *nciop, int doUnlink) if(nciop->fd > 0) { status = nciop->sync(nciop); (void) close(nciop->fd); - } + } if(doUnlink) (void) unlink(nciop->path); ncio_px_free(nciop); return status; } -static int +static int ncio_spx_close(ncio *nciop, int doUnlink) { int status = ENOERR;