mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-11-21 03:13:42 +08:00
Moved lseek call out of assert statement into an explicit check. JIRA NCF-312.
This commit is contained in:
parent
51e3cc4b06
commit
4286822b91
130
libsrc/posixio.c
130
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;
|
||||
|
Loading…
Reference in New Issue
Block a user