int ncio_create(const char *path, int ioflags, size_t initialsz, off_t igeto, size_t igetsz, size_t *sizehintp, ncio **nciopp, void **const igetvpp) { ncio *nciop; #ifdef _WIN32_WCE char* oflags = "bw+"; /*==?(O_RDWR|O_CREAT|O_TRUNC) && binary*/ #else char* oflags = "w+"; /*==?(O_RDWR|O_CREAT|O_TRUNC);*/ #endif FILE* f; int i,fd; int status = ENOERR; if(initialsz < (size_t)igeto + igetsz) initialsz = (size_t)igeto + igetsz; fSet(ioflags, NC_WRITE); if(path == NULL || *path == 0) return EINVAL; nciop = ncio_new(path, ioflags); if(nciop == NULL) return ENOMEM; if(fIsSet(ioflags, NC_NOCLOBBER)) { /* Since we do not have use of the O_EXCL flag, we need to fake it */ #ifdef WINCE f = fopen(path,"rb"); #else f = fopen(path,"r"); #endif if(f != NULL) { /* do not overwrite */ (void)fclose(f); return EEXIST; } } f = fopen(path, oflags); if(f == NULL) { status = errno; goto unwind_new; } /* Locate an open pseudo file descriptor */ fd = -1; for(i=1;i<fdmax;i++) {if(descriptors[i] == NULL) {fd=i;break;}} if(fd < 0) {fd = fdmax; fdmax++;} descriptors[fd] = f; *((int *)&nciop->fd) = fd; /* cast away const */ if(*sizehintp < NCIO_MINBLOCKSIZE || *sizehintp > NCIO_MAXBLOCKSIZE) { /* Use default */ *sizehintp = blksize(fd); } else { *sizehintp = M_RNDUP(*sizehintp); } status = ncio_fileio_init2(nciop, sizehintp); if(status != ENOERR) goto unwind_open; if(initialsz != 0) { status = fgrow(f, (off_t)initialsz); if(status != ENOERR) goto unwind_open; } if(igetsz != 0) { status = nciop->get(nciop, igeto, igetsz, RGN_WRITE, igetvpp); if(status != ENOERR) goto unwind_open; } *nciopp = nciop; return ENOERR; unwind_open: (void) fclose(descriptors[fd]); descriptors[fd] = NULL; /* ?? unlink */ /*FALLTHRU*/ unwind_new: ncio_free(nciop); return status; }
/* Create a file, and the ncio struct to go with it. This funtion is only called from nc__create_mp. path - path of file to create. 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 - 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 created and inited ncio struct. igetvpp - pointer to pointer which will get the location of ? */ int ncio_create(const char *path, int ioflags, size_t initialsz, off_t igeto, size_t igetsz, size_t *sizehintp, ncio **nciopp, void **const igetvpp) { ncio *nciop; int oflags = (O_RDWR|O_CREAT); int fd; int status; if(initialsz < (size_t)igeto + igetsz) initialsz = (size_t)igeto + igetsz; fSet(ioflags, NC_WRITE); if(path == NULL || *path == 0) return EINVAL; nciop = ncio_new(path, ioflags); if(nciop == NULL) return ENOMEM; if(fIsSet(ioflags, NC_NOCLOBBER)) fSet(oflags, O_EXCL); else fSet(oflags, O_TRUNC); #ifdef O_BINARY fSet(oflags, O_BINARY); #endif #ifdef vms fd = open(path, oflags, NC_DEFAULT_CREAT_MODE, "ctx=stm"); #else /* Should we mess with the mode based on NC_SHARE ?? */ fd = open(path, oflags, NC_DEFAULT_CREAT_MODE); #endif #if 0 (void) fprintf(stderr, "ncio_create(): path=\"%s\"\n", path); (void) fprintf(stderr, "ncio_create(): oflags=0x%x\n", oflags); #endif if(fd < 0) { status = errno; goto unwind_new; } *((int *)&nciop->fd) = fd; /* cast away const */ if(*sizehintp < NCIO_MINBLOCKSIZE || *sizehintp > NCIO_MAXBLOCKSIZE) { /* Use default */ *sizehintp = blksize(fd); } else { *sizehintp = M_RNDUP(*sizehintp); } if(fIsSet(nciop->ioflags, NC_SHARE)) status = ncio_spx_init2(nciop, sizehintp); else status = ncio_px_init2(nciop, sizehintp, 1); if(status != ENOERR) goto unwind_open; if(initialsz != 0) { status = fgrow(fd, (off_t)initialsz); if(status != ENOERR) goto unwind_open; } if(igetsz != 0) { status = nciop->get(nciop, igeto, igetsz, RGN_WRITE, igetvpp); if(status != ENOERR) goto unwind_open; } *nciopp = nciop; return ENOERR; unwind_open: (void) close(fd); /* ?? unlink */ /*FALLTHRU*/ unwind_new: ncio_free(nciop); return status; }
/* This function opens the data file. It is only called from nc.c, from nc__open_mp and nc_delete_mp. 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 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. Here's what the man page has to say: "The argument referenced by chunksize controls a space versus time tradeoff, memory allocated in the netcdf library versus number of system calls. Because of internal requirements, the value may not be set to exactly the value requested. The actual value chosen is returned by reference. Using the value NC_SIZEHINT_DEFAULT causes the library to choose a default. How the system choses the default depends on the system. On many systems, the "preferred I/O block size" is available from the stat() system call, struct stat member st_blksize. If this is available it is used. Lacking that, twice the system pagesize is used. Lacking a call to discover the system pagesize, we just set default chunksize to 8192. The chunksize is a property of a given open netcdf descriptor ncid, it is not a persistent property of the netcdf dataset." nciopp - pointer to pointer that will get address of newly created and inited ncio struct. igetvpp - handle to pass back pointer to data from inital page read, if this were ever used, which it isn't. */ int ncio_open(const char *path, int ioflags, off_t igeto, size_t igetsz, size_t *sizehintp, ncio **nciopp, void **const igetvpp) { ncio *nciop; int oflags = fIsSet(ioflags, NC_WRITE) ? O_RDWR : O_RDONLY; int fd; int status; if(path == NULL || *path == 0) return EINVAL; nciop = ncio_new(path, ioflags); if(nciop == NULL) return ENOMEM; #ifdef O_BINARY fSet(oflags, O_BINARY); #endif #ifdef vms fd = open(path, oflags, 0, "ctx=stm"); #else fd = open(path, oflags, 0); #endif if(fd < 0) { status = errno; goto unwind_new; } *((int *)&nciop->fd) = fd; /* cast away const */ if(*sizehintp < NCIO_MINBLOCKSIZE || *sizehintp > NCIO_MAXBLOCKSIZE) { /* Use default */ *sizehintp = blksize(fd); } else { *sizehintp = M_RNDUP(*sizehintp); } if(fIsSet(nciop->ioflags, NC_SHARE)) status = ncio_spx_init2(nciop, sizehintp); else status = ncio_px_init2(nciop, sizehintp, 0); if(status != ENOERR) goto unwind_open; if(igetsz != 0) { status = nciop->get(nciop, igeto, igetsz, 0, igetvpp); if(status != ENOERR) goto unwind_open; } *nciopp = nciop; return ENOERR; unwind_open: (void) close(fd); /*FALLTHRU*/ unwind_new: ncio_free(nciop); return status; }
int ncio_open(const char *path, int ioflags, off_t igeto, size_t igetsz, size_t *sizehintp, ncio **nciopp, void **const igetvpp) { ncio *nciop; const char *ControlString; int oflags = fIsSet(ioflags, NC_WRITE) ? O_RDWR : O_RDONLY; int fd; int status; struct ffsw stat; if(path == NULL || *path == 0) return EINVAL; nciop = ncio_new(path, ioflags); if(nciop == NULL) return ENOMEM; if ((ControlString = ncio_ffio_assign(path)) == (const char *)NULL) { /* an error occured - just punt */ status = errno; goto unwind_new; } #ifdef NOFFFLUSH /* test whether the global layer is being called for * this file ... if so then can't call FFIO ffflush() * RKO 06/26/98 */ if (strstr(ControlString,"global") != (char *) NULL) { /* use no ffflush version */ *((ncio_syncfunc **)&nciop->sync) = ncio_ffio_sync_noffflush; } #endif /* Orig: fd = ffopens(path, oflags, 0, 0, &stat, ControlString); */ fd = ffopen(path, oflags, 0, 0, &stat); if(fd < 0) { status = errno; goto unwind_new; } *((int *)&nciop->fd) = fd; /* cast away const */ if(*sizehintp < NCIO_MINBLOCKSIZE || *sizehintp > NCIO_MAXBLOCKSIZE) { /* Use default */ *sizehintp = blksize(fd); } else { *sizehintp = M_RNDUP(*sizehintp); } status = ncio_ffio_init2(nciop, sizehintp); if(status != ENOERR) goto unwind_open; if(igetsz != 0) { status = nciop->get(nciop, igeto, igetsz, 0, igetvpp); if(status != ENOERR) goto unwind_open; } *nciopp = nciop; return ENOERR; unwind_open: (void) ffclose(fd); /*FALLTHRU*/ unwind_new: ncio_free(nciop); return status; }