Doxygen Source Code Documentation
ffio.c File Reference
#include "ncconfig.h"#include <assert.h>#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <fcntl.h>#include <ffio.h>#include <unistd.h>#include <string.h>#include <fortran.h>#include "ncio.h"#include "fbits.h"#include "rnd.h"Go to the source code of this file.
| Data Structures | |
| struct | ncio_ffio | 
| Defines | |
| #define | ENOERR 0 | 
| #define | X_INT_MAX 2147483647 | 
| #define | ALWAYS_NC_SHARE 0 | 
| #define | BUFLEN 256 | 
| Typedefs | |
| typedef ncio_ffio | ncio_ffio | 
| Functions | |
| size_t | blksize (int fd) | 
| int | fgrow (const int fd, const off_t len) | 
| int | ffio_pgout (ncio *const nciop, off_t const offset, const size_t extent, const void *const vp, off_t *posp) | 
| int | ffio_pgin (ncio *const nciop, off_t const offset, const size_t extent, void *const vp, size_t *nreadp, off_t *posp) | 
| int | ncio_ffio_rel (ncio *const nciop, off_t offset, int rflags) | 
| int | ncio_ffio_get (ncio *const nciop, off_t offset, size_t extent, int rflags, void **const vpp) | 
| int | ncio_ffio_move (ncio *const nciop, off_t to, off_t from, size_t nbytes, int rflags) | 
| int | ncio_ffio_sync (ncio *const nciop) | 
| void | ncio_ffio_free (void *const pvt) | 
| int | ncio_ffio_init2 (ncio *const nciop, size_t *sizehintp) | 
| void | ncio_ffio_init (ncio *const nciop) | 
| void | ncio_free (ncio *nciop) | 
| ncio * | ncio_new (const char *path, int ioflags) | 
| void | ASNQFILE (_fcd filename, _fcd attribute, int *istat) | 
| void | ASNFILE (_fcd filename, _fcd attribute, int *istat) | 
| const char * | ncio_ffio_assign (const char *filename) | 
| 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) | 
| int | ncio_open (const char *path, int ioflags, off_t igeto, size_t igetsz, size_t *sizehintp, ncio **nciopp, void **const igetvpp) | 
| int | ncio_close (ncio *nciop, int doUnlink) | 
| Variables | |
| const size_t | NCIO_MINBLOCKSIZE = 256 | 
| const size_t | NCIO_MAXBLOCKSIZE = 268435456 | 
Define Documentation
| 
 | 
| 
 | 
| 
 | 
| 
 Definition at line 483 of file ffio.c. Referenced by ncio_ffio_assign(). | 
| 
 | 
| 
 Definition at line 14 of file ffio.c. Referenced by ffio_pgin(), ffio_pgout(), fgrow(), ncio_close(), ncio_create(), ncio_ffio_assign(), ncio_ffio_get(), ncio_ffio_init2(), ncio_ffio_move(), ncio_ffio_rel(), ncio_ffio_sync(), and ncio_open(). | 
| 
 | 
| 
 Definition at line 28 of file ffio.c. Referenced by ncio_ffio_get(). | 
Typedef Documentation
| 
 | 
| 
 | 
Function Documentation
| 
 | ||||||||||||||||
| 
 Referenced by ncio_ffio_assign(). | 
| 
 | ||||||||||||||||
| 
 Referenced by ncio_ffio_assign(). | 
| 
 | 
| 
 Definition at line 44 of file ffio.c. 
 | 
| 
 | ||||||||||||||||||||||||||||
| 
 Definition at line 119 of file ffio.c. References ENOERR, ncio::fd, offset, and X_ALIGN. Referenced by ncio_ffio_get(). 
 00122 {
00123         int status;
00124         ssize_t nread;
00125 
00126 #ifdef X_ALIGN
00127         assert(offset % X_ALIGN == 0);
00128         assert(extent % X_ALIGN == 0);
00129 #endif
00130 
00131         if(*posp != offset)
00132         {
00133                 if(ffseek(nciop->fd, offset, SEEK_SET) != offset)
00134                 {
00135                         status = errno;
00136                         return status;
00137                 }
00138                 *posp = offset;
00139         }
00140 
00141         errno = 0;
00142         nread = ffread(nciop->fd, vp, extent);
00143         if(nread != extent)
00144         {
00145                 status = errno;
00146                 if(nread == -1 || status != ENOERR)
00147                         return status;
00148                 /* else it's okay we read 0. */
00149         }
00150         *nreadp = nread;
00151         *posp += nread;
00152 
00153         return ENOERR;
00154 }
 | 
| 
 | ||||||||||||||||||||||||
| 
 Definition at line 91 of file ffio.c. References ENOERR, ncio::fd, offset, and X_ALIGN. Referenced by ncio_ffio_rel(). 
 00094 {
00095 #ifdef X_ALIGN
00096         assert(offset % X_ALIGN == 0);
00097         assert(extent % X_ALIGN == 0);
00098 #endif
00099 
00100         if(*posp != offset)
00101         {
00102                 if(ffseek(nciop->fd, offset, SEEK_SET) != offset)
00103                 {
00104                         return errno;
00105                 }
00106                 *posp = offset;
00107         }
00108         if(ffwrite(nciop->fd, vp, extent) != extent)
00109         {
00110                 return errno;
00111         }
00112         *posp += extent;
00113 
00114         return ENOERR;
00115 }
 | 
| 
 | ||||||||||||
| 
 Definition at line 62 of file ffio.c. References ENOERR, fd, and sb. 
 00063 {
00064         struct ffc_stat_s sb;
00065         struct ffsw sw;
00066         if (fffcntl(fd, FC_STAT, &sb, &sw) < 0)
00067                 return errno;
00068         if (len < sb.st_size)
00069                 return ENOERR;
00070         {
00071                 const long dumb = 0;
00072                         /* cache current position */
00073                 const off_t pos = ffseek(fd, 0, SEEK_CUR);
00074                 if(pos < 0)
00075                         return errno;
00076                 if (ffseek(fd, len-sizeof(dumb), SEEK_SET) < 0)
00077                         return errno;
00078                 if(ffwrite(fd, (void *)&dumb, sizeof(dumb)) < 0)
00079                         return errno;
00080                 if (ffseek(fd, pos, SEEK_SET) < 0)
00081                         return errno;
00082         }
00083         /* else */
00084         return ENOERR;
00085 }
 | 
| 
 | ||||||||||||
| 
 Definition at line 725 of file ffio.c. References ENOERR, ncio::fd, ncio_free(), ncio::path, ncio::sync, and unlink. 
 | 
| 
 | ||||||||||||||||||||||||||||||||||||
| 
 Definition at line 545 of file ffio.c. References blksize(), ENOERR, ncio::fd, fd, fgrow(), fIsSet, fSet, ncio::get, M_RNDUP, ncio_ffio_assign(), ncio_ffio_init2(), ncio_free(), NCIO_MAXBLOCKSIZE, ncio_new(), ncio_syncfunc, RGN_WRITE, and ncio::sync. 
 00549 {
00550         ncio *nciop;
00551         const char *ControlString;
00552         int oflags = (O_RDWR|O_CREAT|O_TRUNC);
00553         int fd;
00554         int status;
00555         struct ffsw stat;
00556 
00557         if(initialsz < (size_t)igeto + igetsz)
00558                 initialsz = (size_t)igeto + igetsz;
00559 
00560         fSet(ioflags, NC_WRITE);
00561 
00562         if(path == NULL || *path == 0)
00563                 return EINVAL;
00564 
00565         nciop = ncio_new(path, ioflags);
00566         if(nciop == NULL)
00567                 return ENOMEM;
00568 
00569         if ((ControlString = ncio_ffio_assign(path)) == (const char *)NULL) {
00570                 /* an error occured - just punt */
00571                 status = errno;
00572                 goto unwind_new;
00573         }
00574 #ifdef NOFFFLUSH
00575         /* test whether the global layer is being called for
00576          * this file ... if so then can't call FFIO ffflush()
00577          * RKO 06/26/98
00578          */
00579         if (strstr(ControlString,"global") != (char *) NULL) {
00580                 /* use no ffflush version */
00581                 *((ncio_syncfunc **)&nciop->sync)
00582                         = ncio_ffio_sync_noffflush;
00583         }
00584 #endif
00585         if(fIsSet(ioflags, NC_NOCLOBBER))
00586                 fSet(oflags, O_EXCL);
00587 
00588         /* Orig: fd = ffopens(path, oflags, 0666, 0, &stat, ControlString); */
00589         fd = ffopen(path, oflags, 0666, 0, &stat);
00590         if(fd < 0)
00591         {
00592                 status = errno;
00593                 goto unwind_new;
00594         }
00595         *((int *)&nciop->fd) = fd; /* cast away const */
00596 
00597         if(*sizehintp < NCIO_MINBLOCKSIZE || *sizehintp > NCIO_MAXBLOCKSIZE)
00598         {
00599                 /* Use default */
00600                 *sizehintp = blksize(fd);
00601         }
00602         else
00603         {
00604                 *sizehintp = M_RNDUP(*sizehintp);
00605         }
00606 
00607         status = ncio_ffio_init2(nciop, sizehintp);
00608         if(status != ENOERR)
00609                 goto unwind_open;
00610 
00611         if(initialsz != 0)
00612         {
00613                 status = fgrow(fd, (off_t)initialsz);
00614                 if(status != ENOERR)
00615                         goto unwind_open;
00616         }
00617 
00618         if(igetsz != 0)
00619         {
00620                 status = nciop->get(nciop,
00621                                 igeto, igetsz,
00622                                 RGN_WRITE,
00623                                 igetvpp);
00624                 if(status != ENOERR)
00625                         goto unwind_open;
00626         }
00627 
00628         *nciopp = nciop;
00629         return ENOERR;
00630 
00631 unwind_open:
00632         (void) ffclose(fd);
00633         /* ?? unlink */
00634         /*FALLTHRU*/
00635 unwind_new:
00636         ncio_free(nciop);
00637         return status;
00638 }
 | 
| 
 | 
| 
 Definition at line 485 of file ffio.c. References ASNFILE(), ASNQFILE(), BUFLEN, ENOERR, and getenv(). Referenced by ncio_create(), and ncio_open(). 
 00485                                        {
00486         static char buffer[BUFLEN];
00487         int istat;
00488         _fcd fnp, fbp;
00489         char *envstr;
00490         char *xtra_assign;
00491         char emptystr='\0';
00492 
00493 /* put things into known states */
00494         memset(buffer,'\0',BUFLEN);
00495         errno = ENOERR;
00496 
00497 /* set up Fortran character pointers */
00498         fnp = _cptofcd((char *)filename, strlen(filename));
00499         fbp = _cptofcd(buffer, BUFLEN);
00500 
00501 /* see if the user has "assigned" to this file */
00502         ASNQFILE(fnp, fbp, &istat);
00503         if (istat == 0) {       /* user has already specified an assign */
00504                 return buffer;
00505         } else if (istat > 0 || istat < -1) {   /* error occured */
00506                 errno = NC_EINVAL;              /* as good as any */
00507                 return (const char *) NULL;
00508         } /* istat = -1 -> no assign for file */
00509         envstr = getenv("NETCDF_FFIOSPEC");
00510         if(envstr == (char *) NULL) {
00511                  envstr = "bufa:336:2";         /* this should be macroized */
00512         }
00513         
00514         /* Insertion by Olaf Heudecker, AWI-Bremerhaven, 12.8.1998
00515            to allow more versatile FFIO-assigns */
00516         /* this is unnecessary and could have been included
00517          * into the NETCDF_FFIOSPEC environment variable */
00518         xtra_assign = getenv("NETCDF_XFFIOSPEC");
00519         if(xtra_assign == (char *) NULL) {
00520                 xtra_assign=&emptystr;
00521         }
00522         if (strlen(envstr)+strlen(xtra_assign) + 4 > BUFLEN) {
00523         /* Error: AssignCommand too long */
00524                 errno=E2BIG;
00525                 return (const char *) NULL;
00526         }
00527         (void) sprintf(buffer,"-F %s %s", envstr,xtra_assign);
00528         fbp = _cptofcd(buffer, strlen(buffer));
00529         ASNFILE(fnp, fbp, &istat);
00530         if (istat == 0) {       /* success */
00531                 return buffer;
00532         } else {                /* error */
00533                 errno = NC_EINVAL;
00534                 return (const char *) NULL;
00535         }
00536 }
 | 
| 
 | 
| 
 Definition at line 365 of file ffio.c. References ncio_ffio::bf_base, ncio_ffio::bf_cnt, ncio_ffio::bf_extent, ncio_ffio::bf_offset, free, and OFF_NONE. Referenced by ncio_ffio_init(). 
 | 
| 
 | ||||||||||||||||||||||||
| 
 Definition at line 199 of file ffio.c. References ncio_ffio::bf_base, ncio_ffio::bf_cnt, ncio_ffio::bf_extent, ncio_ffio::bf_offset, ENOERR, ffio_pgin(), fIsSet, free, ncio::ioflags, malloc, offset, ncio_ffio::pos, ncio::pvt, RGN_WRITE, X_ALIGN, and X_INT_MAX. Referenced by ncio_ffio_init(), and ncio_ffio_move(). 
 00203 {
00204         ncio_ffio *ffp = (ncio_ffio *)nciop->pvt;
00205         int status = ENOERR;
00206 #ifdef X_ALIGN
00207         size_t rem;
00208 #endif
00209         
00210         if(fIsSet(rflags, RGN_WRITE) && !fIsSet(nciop->ioflags, NC_WRITE))
00211                 return EPERM; /* attempt to write readonly file */
00212 
00213         assert(extent != 0);
00214         assert(extent < X_INT_MAX); /* sanity check */
00215         assert(offset < X_INT_MAX); /* sanity check */
00216 
00217         assert(ffp->bf_cnt == 0);
00218 
00219 #ifdef X_ALIGN
00220         /* round to seekable boundaries */
00221         rem = offset % X_ALIGN;
00222         if(rem != 0)
00223         {
00224                 offset -= rem;
00225                 extent += rem;
00226         }
00227 
00228         {
00229                 const size_t rndup = extent % X_ALIGN;
00230                 if(rndup != 0)
00231                         extent += X_ALIGN - rndup;
00232         }
00233 
00234         assert(offset % X_ALIGN == 0);
00235         assert(extent % X_ALIGN == 0);
00236 #endif
00237 
00238         if(ffp->bf_extent < extent)
00239         {
00240                 if(ffp->bf_base != NULL)
00241                 {
00242                         free(ffp->bf_base);
00243                         ffp->bf_base = NULL;
00244                         ffp->bf_extent = 0;
00245                 }
00246                 assert(ffp->bf_extent == 0);
00247                 ffp->bf_base = malloc(extent);
00248                 if(ffp->bf_base == NULL)
00249                         return ENOMEM;
00250                 ffp->bf_extent = extent;
00251         }
00252 
00253         status = ffio_pgin(nciop, offset,
00254                  extent,
00255                  ffp->bf_base,
00256                  &ffp->bf_cnt, &ffp->pos);
00257         if(status != ENOERR)
00258                 return status;
00259 
00260         ffp->bf_offset = offset;
00261 
00262         if(ffp->bf_cnt < extent)
00263         {
00264                 (void) memset((char *)ffp->bf_base + ffp->bf_cnt, 0,
00265                         extent - ffp->bf_cnt);
00266                 ffp->bf_cnt = extent;
00267         }
00268 
00269 
00270 #ifdef X_ALIGN
00271         *vpp = (char *)ffp->bf_base + rem;
00272 #else
00273         *vpp = (char *)ffp->bf_base;
00274 #endif
00275         return ENOERR;
00276 }
 | 
| 
 | 
| 
 | ||||||||||||
| 
 Definition at line 383 of file ffio.c. References ncio_ffio::bf_base, ncio_ffio::bf_extent, ENOERR, ncio::fd, malloc, and ncio::pvt. Referenced by ncio_create(), and ncio_open(). 
 00384 {
00385         ncio_ffio *ffp = (ncio_ffio *)nciop->pvt;
00386 
00387         assert(nciop->fd >= 0);
00388 
00389         ffp->bf_extent = *sizehintp;
00390 
00391         assert(ffp->bf_base == NULL);
00392 
00393         /* this is separate allocation because it may grow */
00394         ffp->bf_base = malloc(ffp->bf_extent);
00395         if(ffp->bf_base == NULL)
00396         {
00397                 ffp->bf_extent = 0;
00398                 return ENOMEM;
00399         }
00400         /* else */
00401         return ENOERR;
00402 }
 | 
| 
 | ||||||||||||||||||||||||
| 
 Definition at line 280 of file ffio.c. References base, ENOERR, ncio_ffio_get(), ncio_ffio_rel(), RGN_MODIFIED, RGN_NOLOCK, and RGN_WRITE. Referenced by ncio_ffio_init(). 
 00282 {
00283         int status = ENOERR;
00284         off_t lower = from;     
00285         off_t upper = to;
00286         char *base;
00287         size_t diff = upper - lower;
00288         size_t extent = diff + nbytes;
00289 
00290         rflags &= RGN_NOLOCK; /* filter unwanted flags */
00291 
00292         if(to == from)
00293                 return ENOERR; /* NOOP */
00294         
00295         if(to > from)
00296         {
00297                 /* growing */
00298                 lower = from;   
00299                 upper = to;
00300         }
00301         else
00302         {
00303                 /* shrinking */
00304                 lower = to;
00305                 upper = from;
00306         }
00307 
00308         diff = upper - lower;
00309         extent = diff + nbytes;
00310 
00311         status = ncio_ffio_get(nciop, lower, extent, RGN_WRITE|rflags,
00312                         (void **)&base);
00313 
00314         if(status != ENOERR)
00315                 return status;
00316 
00317         if(to > from)
00318                 (void) memmove(base + diff, base, nbytes); 
00319         else
00320                 (void) memmove(base, base + diff, nbytes); 
00321                 
00322         (void) ncio_ffio_rel(nciop, lower, RGN_MODIFIED);
00323 
00324         return status;
00325 }
 | 
| 
 | ||||||||||||||||
| 
 Definition at line 169 of file ffio.c. References ncio_ffio::bf_base, ncio_ffio::bf_cnt, ncio_ffio::bf_extent, ncio_ffio::bf_offset, ENOERR, ffio_pgout(), fIsSet, ncio::ioflags, OFF_NONE, offset, ncio_ffio::pos, ncio::pvt, RGN_MODIFIED, and X_ALIGN. Referenced by ncio_ffio_init(), and ncio_ffio_move(). 
 00170 {
00171         ncio_ffio *ffp = (ncio_ffio *)nciop->pvt;
00172         int status = ENOERR;
00173 
00174         assert(ffp->bf_offset <= offset);
00175         assert(ffp->bf_cnt != 0);
00176         assert(ffp->bf_cnt <= ffp->bf_extent);
00177 #ifdef X_ALIGN
00178         assert(offset < ffp->bf_offset + X_ALIGN);
00179         assert(ffp->bf_cnt % X_ALIGN == 0 );
00180 #endif
00181 
00182         if(fIsSet(rflags, RGN_MODIFIED))
00183         {
00184                 if(!fIsSet(nciop->ioflags, NC_WRITE))
00185                         return EPERM; /* attempt to write readonly file */
00186 
00187                 status = ffio_pgout(nciop, ffp->bf_offset,
00188                         ffp->bf_cnt,
00189                         ffp->bf_base, &ffp->pos);
00190                 /* if error, invalidate buffer anyway */
00191         }
00192         ffp->bf_offset = OFF_NONE;
00193         ffp->bf_cnt = 0;
00194         return status;
00195 }
 | 
| 
 | 
| 
 Definition at line 357 of file ffio.c. References ENOERR, and ncio::fd. Referenced by ncio_ffio_init(). 
 | 
| 
 | 
| 
 Definition at line 426 of file ffio.c. References free, ncio::free, and ncio::pvt. 
 | 
| 
 | ||||||||||||
| 
 Definition at line 439 of file ffio.c. References ncio::fd, fIsSet, fSet, ncio::ioflags, M_RNDUP, malloc, ncio_ffio_init(), ncio::path, and ncio::pvt. 
 00440 {
00441         size_t sz_ncio = M_RNDUP(sizeof(ncio));
00442         size_t sz_path = M_RNDUP(strlen(path) +1);
00443         size_t sz_ncio_pvt;
00444         ncio *nciop;
00445  
00446 #if ALWAYS_NC_SHARE /* DEBUG */
00447         fSet(ioflags, NC_SHARE);
00448 #endif
00449 
00450         if(fIsSet(ioflags, NC_SHARE))
00451                 fprintf(stderr, "NC_SHARE not implemented for ffio\n");
00452 
00453         sz_ncio_pvt = sizeof(ncio_ffio);
00454 
00455         nciop = (ncio *) malloc(sz_ncio + sz_path + sz_ncio_pvt);
00456         if(nciop == NULL)
00457                 return NULL;
00458         
00459         nciop->ioflags = ioflags;
00460         *((int *)&nciop->fd) = -1; /* cast away const */
00461 
00462         nciop->path = (char *) ((char *)nciop + sz_ncio);
00463         (void) strcpy((char *)nciop->path, path); /* cast away const */
00464 
00465                                 /* cast away const */
00466         *((void **)&nciop->pvt) = (void *)(nciop->path + sz_path);
00467 
00468         ncio_ffio_init(nciop);
00469 
00470         return nciop;
00471 }
 | 
| 
 | ||||||||||||||||||||||||||||||||
| 
 Definition at line 642 of file ffio.c. References blksize(), ENOERR, ncio::fd, fd, fIsSet, ncio::get, M_RNDUP, ncio_ffio_assign(), ncio_ffio_init2(), ncio_free(), NCIO_MAXBLOCKSIZE, ncio_new(), ncio_syncfunc, and ncio::sync. 
 00646 {
00647         ncio *nciop;
00648         const char *ControlString;
00649         int oflags = fIsSet(ioflags, NC_WRITE) ? O_RDWR : O_RDONLY;
00650         int fd;
00651         int status;
00652         struct ffsw stat;
00653 
00654         if(path == NULL || *path == 0)
00655                 return EINVAL;
00656 
00657         nciop = ncio_new(path, ioflags);
00658         if(nciop == NULL)
00659                 return ENOMEM;
00660 
00661         if ((ControlString = ncio_ffio_assign(path)) == (const char *)NULL) {
00662                 /* an error occured - just punt */
00663                 status = errno;
00664                 goto unwind_new;
00665         }
00666 #ifdef NOFFFLUSH
00667         /* test whether the global layer is being called for
00668          * this file ... if so then can't call FFIO ffflush()
00669          * RKO 06/26/98
00670          */
00671         if (strstr(ControlString,"global") != (char *) NULL) {
00672                 /* use no ffflush version */
00673                 *((ncio_syncfunc **)&nciop->sync)
00674                         = ncio_ffio_sync_noffflush;
00675         }
00676 #endif
00677 
00678         /* Orig: fd = ffopens(path, oflags, 0, 0, &stat, ControlString); */
00679         fd = ffopen(path, oflags, 0, 0, &stat);
00680 
00681         if(fd < 0)
00682         {
00683                 status = errno;
00684                 goto unwind_new;
00685         }
00686         *((int *)&nciop->fd) = fd; /* cast away const */
00687 
00688         if(*sizehintp < NCIO_MINBLOCKSIZE || *sizehintp > NCIO_MAXBLOCKSIZE)
00689         {
00690                 /* Use default */
00691                 *sizehintp = blksize(fd);
00692         }
00693         else
00694         {
00695                 *sizehintp = M_RNDUP(*sizehintp);
00696         }
00697 
00698         status = ncio_ffio_init2(nciop, sizehintp);
00699         if(status != ENOERR)
00700                 goto unwind_open;
00701 
00702         if(igetsz != 0)
00703         {
00704                 status = nciop->get(nciop,
00705                                 igeto, igetsz,
00706                                 0,
00707                                 igetvpp);
00708                 if(status != ENOERR)
00709                         goto unwind_open;
00710         }
00711 
00712         *nciopp = nciop;
00713         return ENOERR;
00714 
00715 unwind_open:
00716         (void) ffclose(fd);
00717         /*FALLTHRU*/
00718 unwind_new:
00719         ncio_free(nciop);
00720         return status;
00721 }
 | 
Variable Documentation
| 
 | 
| 
 Definition at line 542 of file ffio.c. Referenced by ncio_create(), and ncio_open(). | 
| 
 | 
| 
 | 
 
                             
                             
                             
                             
                             
                             
                             
                             
                             
                             
                             
                             
 
 
 
 
       
	   
	   
	   
	  