mirror of
https://github.com/Unidata/netcdf-c.git
synced 2025-01-18 15:55:12 +08:00
fix bug in memio.c realloc code
This commit is contained in:
parent
3e444c39d8
commit
353b7ebf53
4
cf
4
cf
@ -6,7 +6,7 @@ cmds=$@
|
||||
fi
|
||||
|
||||
#HDF5=1
|
||||
#DAP=1
|
||||
DAP=1
|
||||
#CDMR=1
|
||||
#RPC=1
|
||||
#PGI=1
|
||||
@ -19,7 +19,7 @@ cmds=""
|
||||
#cmds="all"
|
||||
#cmds="all check"
|
||||
#cmds="all dist"
|
||||
cmds="all distcheck"
|
||||
#cmds="all distcheck"
|
||||
#cmds="$cmds install"
|
||||
fi
|
||||
|
||||
|
@ -18,6 +18,12 @@
|
||||
#endif
|
||||
#include "nc.h"
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SSIZE_T
|
||||
#define ssize_t int
|
||||
#endif
|
||||
@ -60,13 +66,6 @@
|
||||
#undef X_ALIGN
|
||||
#endif
|
||||
|
||||
/* Define the amount by which memory is incremented on realloc */
|
||||
#define DEFAULT_BLOCKSIZE (0x2000)
|
||||
|
||||
#define TACTIC_INCR 1
|
||||
#define TACTIC_DOUBLE 2
|
||||
#define TACTIC TACTIC_DOUBLE
|
||||
|
||||
/* Private data for memio */
|
||||
|
||||
typedef struct NCMEMIO {
|
||||
@ -90,6 +89,8 @@ static int memio_close(ncio* nciop, int);
|
||||
/* Mnemonic */
|
||||
#define DOOPEN 1
|
||||
|
||||
static long pagesize = 0;
|
||||
|
||||
/* Create a new ncio struct to hold info about the file. */
|
||||
static int
|
||||
memio_new(const char* path, int ioflags, off_t initialsize, ncio** nciopp, NCMEMIO** memiop)
|
||||
@ -98,13 +99,17 @@ memio_new(const char* path, int ioflags, off_t initialsize, ncio** nciopp, NCMEM
|
||||
ncio* nciop = NULL;
|
||||
NCMEMIO* memio = NULL;
|
||||
int openfd = -1;
|
||||
|
||||
if(pagesize == 0) {
|
||||
#if defined HAVE_SYSCONF
|
||||
long pagesize = sysconf(_SC_PAGE_SIZE);
|
||||
pagesize = sysconf(_SC_PAGE_SIZE);
|
||||
#elif defined HAVE_GETPAGESIZE
|
||||
long pagesize = getpagesize();
|
||||
pagesize = getpagesize();
|
||||
#else
|
||||
long pagesize = 4096; /* good guess */
|
||||
pagesize = 4096; /* good guess */
|
||||
#endif
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
|
||||
/* Always force the allocated size to be a multiple of pagesize */
|
||||
@ -218,6 +223,10 @@ memio_create(const char* path, int ioflags,
|
||||
if(memio->memory == NULL) {status = NC_ENOMEM; goto unwind_open;}
|
||||
} /*!persist*/
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,"memio_create: initial memory: %lu/%lu\n",(unsigned long)memio->memory,(unsigned long)memio->alloc);
|
||||
#endif
|
||||
|
||||
fd = nc__pseudofd();
|
||||
*((int* )&nciop->fd) = fd;
|
||||
|
||||
@ -234,7 +243,7 @@ memio_create(const char* path, int ioflags,
|
||||
}
|
||||
|
||||
/* Pick a default sizehint */
|
||||
if(sizehintp) *sizehintp = DEFAULT_BLOCKSIZE;
|
||||
if(sizehintp) *sizehintp = pagesize;
|
||||
|
||||
*nciopp = nciop;
|
||||
return NC_NOERR;
|
||||
@ -309,6 +318,10 @@ memio_open(const char* path,
|
||||
memio->memory = (char*)malloc(memio->alloc);
|
||||
if(memio->memory == NULL) {status = NC_ENOMEM; goto unwind_open;}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,"memio_open: initial memory: %lu/%lu\n",(unsigned long)memio->memory,(unsigned long)memio->alloc);
|
||||
#endif
|
||||
|
||||
/* Read the file into the memio memory */
|
||||
/* We need to do multiple reads because there is no
|
||||
guarantee that the amount read will be the full amount */
|
||||
@ -383,28 +396,28 @@ memio_pad_length(ncio* nciop, off_t length)
|
||||
if(!fIsSet(nciop->ioflags, NC_WRITE))
|
||||
return EPERM; /* attempt to write readonly file*/
|
||||
|
||||
/* Realloc the allocated memory */
|
||||
if(memio->locked > 0)
|
||||
return NC_EDISKLESS;
|
||||
|
||||
if(length > memio->alloc) {
|
||||
off_t newsize;
|
||||
char* newmem;
|
||||
switch(TACTIC) {
|
||||
case TACTIC_DOUBLE:
|
||||
newsize = (memio->alloc * 2);
|
||||
break;
|
||||
case TACTIC_INCR:
|
||||
default:
|
||||
newsize = length + (length % DEFAULT_BLOCKSIZE);
|
||||
break;
|
||||
}
|
||||
/* Realloc the allocated memory to a multiple of the pagesize*/
|
||||
off_t newsize = length;
|
||||
void* newmem = NULL;
|
||||
/* Round to a multiple of pagesize */
|
||||
if((newsize % pagesize) != 0)
|
||||
newsize += (pagesize - (newsize % pagesize));
|
||||
|
||||
newmem = (char*)realloc(memio->memory,newsize);
|
||||
if(newmem == NULL) return NC_ENOMEM;
|
||||
|
||||
/* zero out the extra memory */
|
||||
memset((void*)(newmem+memio->alloc),0,(newsize - memio->alloc));
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,"realloc: %lu/%lu -> %lu/%lu\n",
|
||||
(unsigned long)memio->memory,(unsigned long)memio->alloc,
|
||||
(unsigned long)newmem,(unsigned long)newsize);
|
||||
#endif
|
||||
memio->memory = newmem;
|
||||
memio->alloc = newsize;
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ main(int argc, char **argv)
|
||||
#ifdef USE_DAP
|
||||
#ifdef ENABLE_DAP_REMOTE_TESTS
|
||||
printf("*** testing simple opendap open/close...");
|
||||
printf(" url=%s\n",URL);
|
||||
{
|
||||
int ncid;
|
||||
|
||||
|
@ -6,7 +6,6 @@
|
||||
but they use HDF5 the same way that netCDF-4 does, so if these
|
||||
tests don't work, than netCDF-4 won't work either.
|
||||
|
||||
$Id$
|
||||
*/
|
||||
#include <config.h>
|
||||
#include <nc_tests.h>
|
||||
|
Loading…
Reference in New Issue
Block a user