ocssw  1.0
/disk01/web/ocssw/build/src/libw3/bacio.v1.3.c (r7484/r4181)
Go to the documentation of this file.
00001 /* Fortran-callable routines to read and write characther (bacio) and */
00002 /*   numeric (banio) data byte addressably                            */
00003 /* Robert Grumbine  16 March 1998 */
00004 /*  v1.1: Put diagnostic output under control of define VERBOSE or QUIET */
00005 /*        Add option of non-seeking read/write                           */
00006 /*        Return code for fewer data read/written than requested */
00007 /*  v1.2: Add cray compatibility  20 April 1998                  */
00008 
00009 #include <stdio.h>
00010 #include <sys/types.h>
00011 #include <sys/stat.h>
00012 #include <fcntl.h>
00013 #include <unistd.h>
00014 #include <ctype.h>
00015 #include <string.h>
00016 
00017 /* Include the C library file for definition/control */
00018 /* Things that might be changed for new systems are there. */
00019 /* This source file should not (need to) be edited, merely recompiled */
00020 #include "clib.h"
00021 
00022 
00023 /* Return Codes:  */
00024 /*  0    All was well                                   */
00025 /* -1    Tried to open read only _and_ write only       */
00026 /* -2    Tried to read and write in the same call       */
00027 /* -3    Internal failure in name processing            */
00028 /* -4    Failure in opening file                        */
00029 /* -5    Tried to read on a write-only file             */ 
00030 /* -6    Failed in read to find the 'start' location    */
00031 /* -7    Tried to write to a read only file             */
00032 /* -8    Failed in write to find the 'start' location   */
00033 /* -9    Error in close                                 */
00034 /* -10   Read or wrote fewer data than requested        */
00035 
00036 /* Note: In your Fortran code, call bacio, not bacio_.  */
00037 /*int bacio_(int * mode, int * start, int * size, int * no, int * nactual,   */ 
00038 /*          int * fdes, const char *fname, char *data, int  namelen,         */ 
00039 /*          int  datanamelen)                                                */
00040 /* Arguments: */
00041 /* Mode is the integer specifying operations to be performed                 */
00042 /*    see the clib.inc file for the values.  Mode is obtained                */
00043 /*    by adding together the values corresponding to the operations          */
00044 /*    The best method is to include the clib.inc file and refer to the       */
00045 /*    names for the operations rather than rely on hard-coded values         */
00046 /* Start is the byte number to start your operation from.  0 is the first    */
00047 /*    byte in the file, not 1.                                               */
00048 /* Newpos is the position in the file after a read or write has been         */
00049 /*    performed.  You'll need this if you're doing 'seeking' read/write      */
00050 /* Size is the size of the objects you are trying to read.  Rely on the      */
00051 /*    values in the locale.inc file.  Types are CHARACTER, INTEGER, REAL,    */
00052 /*    COMPLEX.  Specify the correct value by using SIZEOF_type, where type   */
00053 /*    is one of these.  (After having included the locale.inc file)          */
00054 /* no is the number of things to read or write (characters, integers,        */
00055 /*                                                              whatever)    */
00056 /* nactual is the number of things actually read or written.  Check that     */
00057 /*    you got what you wanted.                                               */
00058 /* fdes is an integer 'file descriptor'.  This is not a Fortran Unit Number  */
00059 /*    You can use it, however, to refer to files you've previously opened.   */
00060 /* fname is the name of the file.  This only needs to be defined when you    */
00061 /*    are opening a file.  It must be (on the Fortran side) declared as      */
00062 /*    CHARACTER*N, where N is a length greater than or equal to the length   */
00063 /*    of the file name.  CHARACTER*1 fname[80] (for example) will fail.      */
00064 /* data is the name of the entity (variable, vector, array) that you want    */
00065 /*    to write data out from or read it in to.  The fact that C is declaring */
00066 /*    it to be a char * does not affect your fortran.                        */
00067 /* namelen - Do NOT specify this.  It is created automagically by the        */
00068 /*    Fortran compiler                                                       */
00069 /* datanamelen - Ditto                                                       */ 
00070 
00071 
00072 /* What is going on here is that although the Fortran caller will always */
00073 /*   be calling bacio, the called C routine name will change from system */
00074 /*   to system. */
00075 #ifdef CRAY90
00076   #include <fortran.h>
00077   int BACIO
00078          (int * mode, int * start, int *newpos, int * size, int * no, 
00079           int * nactual, int * fdes, 
00080           _fcd fcd_fname, _fcd fcd_datary) { 
00081   char *fname, *datary;
00082   int namelen;
00083 #endif
00084 #ifdef HP
00085   int bacio
00086          (int * mode, int * start, int *newpos, int * size, int * no, 
00087           int * nactual, int * fdes, const char *fname, char *datary, 
00088           int  namelen, int  datanamelen) {
00089 #endif
00090 #ifdef SGI
00091   int bacio_
00092          (int * mode, int * start, int *newpos, int * size, int * no, 
00093           int * nactual, int * fdes, const char *fname, char *datary, 
00094           int  namelen, int  datanamelen) {
00095 #endif
00096 #ifdef LINUX
00097   int bacio_
00098          (int * mode, int * start, int *newpos, int * size, int * no, 
00099           int * nactual, int * fdes, const char *fname, char *datary, 
00100           int  namelen, int  datanamelen) {
00101 #else
00102 #ifdef MACINTOSH
00103   int bacio_
00104          (int * mode, int * start, int *newpos, int * size, int * no, 
00105           int * nactual, int * fdes, const char *fname, char *datary, 
00106           int  namelen, int  datanamelen) {
00107 #endif
00108 #endif
00109 #ifdef LINUXF90
00110   int BACIO
00111          (int * mode, int * start, int *newpos, int * size, int * no, 
00112           int * nactual, int * fdes, const char *fname, char *datary, 
00113           int  namelen, int  datanamelen) {
00114 #endif
00115 #ifdef VPP5000
00116   int bacio_
00117          (int * mode, int * start, int *newpos, int * size, int * no, 
00118           int * nactual, int * fdes, const char *fname, char *datary, 
00119           int  namelen, int  datanamelen) {
00120 #endif
00121 #ifdef IBM4
00122   int bacio
00123          (int * mode, int * start, int *newpos, int * size, int * no, 
00124           int * nactual, int * fdes, const char *fname, char *datary, 
00125           int  namelen, int  datanamelen) {
00126 #endif
00127 #ifdef IBM8
00128   int64_t bacio
00129          (int64_t * mode, int64_t * start, int64_t *newpos,
00130           int64_t * size, int64_t * no, 
00131           int64_t * nactual, int64_t  * fdes, const char *fname,
00132           char *datary, 
00133           int64_t namelen, int64_t datanamelen) {
00134 #endif
00135   int i, j, jret, seekret;
00136   char *realname, *tempchar;
00137   int tcharval;
00138   size_t count;
00139 
00140 /* Initialization(s) */
00141   *nactual = 0;
00142 
00143 /* Check for illegal combinations of options */
00144   if (( BAOPEN_RONLY & *mode) &&
00145      ( (BAOPEN_WONLY & *mode) || (BAOPEN_WONLY_TRUNC & *mode) || (BAOPEN_WONLY_APPEND & *mode) ) ) {
00146      #ifdef VERBOSE
00147        printf("illegal -- trying to open both read only and write only\n");
00148      #endif
00149      return -1;
00150   }
00151   if ( (BAREAD & *mode ) && (BAWRITE & *mode) ) {
00152      #ifdef VERBOSE
00153        printf("illegal -- trying to both read and write in the same call\n");
00154      #endif
00155      return -2;
00156   }
00157 
00158 /* This section handles Fortran to C translation of strings so as to */
00159 /*   be able to open the files Fortran is expecting to be opened.    */
00160   #ifdef CRAY90
00161     namelen = _fcdlen(fcd_fname);
00162     fname   = _fcdtocp(fcd_fname);
00163   #endif
00164   if ( (BAOPEN_RONLY & *mode) || (BAOPEN_WONLY & *mode) || 
00165        (BAOPEN_WONLY_TRUNC & *mode) || (BAOPEN_WONLY_APPEND & *mode) ||
00166        (BAOPEN_RW & *mode) ) {
00167     #ifdef VERBOSE
00168       printf("Will be opening a file %s %d\n", fname, namelen); fflush(stdout);
00169       printf("Strlen %d namelen %d\n", strlen(fname), namelen); fflush(stdout);
00170     #endif
00171     realname = (char *) malloc( namelen * sizeof(char) ) ;
00172     if (realname == NULL) { 
00173       #ifdef VERBOSE
00174         printf("failed to mallocate realname %d = namelen\n", namelen);
00175         fflush(stdout);
00176       #endif
00177       return -3;
00178     }
00179     tempchar = (char *) malloc(sizeof(char) * 1 ) ;
00180     i = 0;
00181     j = 0;
00182     *tempchar = fname[i];
00183     tcharval = *tempchar;
00184     while (i == j && i < namelen ) {
00185        fflush(stdout); 
00186        if ( isgraph(tcharval) ) {
00187          realname[j] = fname[i];
00188          j += 1;
00189        }
00190        i += 1;
00191        *tempchar = fname[i];
00192        tcharval = *tempchar;
00193     }
00194     #ifdef VERBOSE
00195       printf("i,j = %d %d\n",i,j); fflush(stdout);
00196     #endif
00197     realname[j] = '\0';
00198   } 
00199    
00200 /* Open files with correct read/write and file permission. */
00201   if (BAOPEN_RONLY & *mode) {
00202     #ifdef VERBOSE
00203       printf("open read only %s\n", realname);
00204     #endif
00205      *fdes = open(realname, O_RDONLY , S_IRWXU | S_IRWXG | S_IRWXO );
00206   }
00207   else if (BAOPEN_WONLY & *mode ) {
00208     #ifdef VERBOSE
00209       printf("open write only %s\n", realname);
00210     #endif
00211      *fdes = open(realname, O_WRONLY | O_CREAT , S_IRWXU | S_IRWXG | S_IRWXO );
00212   }
00213   else if (BAOPEN_WONLY_TRUNC & *mode ) {
00214     #ifdef VERBOSE
00215       printf("open write only with truncation %s\n", realname);
00216     #endif
00217      *fdes = open(realname, O_WRONLY | O_CREAT | O_TRUNC , S_IRWXU | S_IRWXG | S_IRWXO );
00218   }
00219   else if (BAOPEN_WONLY_APPEND & *mode ) {
00220     #ifdef VERBOSE
00221       printf("open write only with append %s\n", realname);
00222     #endif
00223      *fdes = open(realname, O_WRONLY | O_CREAT | O_APPEND , S_IRWXU | S_IRWXG | S_IRWXO );
00224   }
00225   else if (BAOPEN_RW & *mode) {
00226     #ifdef VERBOSE
00227       printf("open read-write %s\n", realname);
00228     #endif
00229      *fdes = open(realname, O_RDWR | O_CREAT , S_IRWXU | S_IRWXG | S_IRWXO );
00230   }
00231   else {
00232     #ifdef VERBOSE
00233       printf("no openings\n");
00234     #endif
00235   }
00236   if (*fdes < 0) {
00237     #ifdef VERBOSE
00238       printf("error in file descriptor! *fdes %d\n", *fdes);
00239     #endif
00240     return -4;
00241   }
00242   else {
00243     #ifdef VERBOSE
00244       printf("file descriptor = %d\n",*fdes );
00245     #endif
00246   }
00247 
00248 
00249 /* Read data as requested */
00250   if (BAREAD & *mode &&
00251    ( (BAOPEN_WONLY & *mode) || (BAOPEN_WONLY_TRUNC & *mode) || (BAOPEN_WONLY_APPEND & *mode) ) ) {
00252     #ifdef VERBOSE
00253       printf("Error, trying to read while in write only mode!\n");
00254     #endif
00255     return -5;
00256   }
00257   else if (BAREAD & *mode ) {
00258   /* Read in some data */
00259     if (! (*mode & NOSEEK) ) {
00260       seekret = lseek(*fdes, *start, SEEK_SET);
00261       if (seekret == -1) {
00262         #ifdef VERBOSE
00263           printf("error in seeking to %d\n",*start);
00264         #endif
00265         return -6;
00266       }
00267       #ifdef VERBOSE
00268       else {
00269          printf("Seek successful, seek ret %d, start %d\n", seekret, *start);
00270       }
00271       #endif
00272     }
00273     #ifdef CRAY90
00274       datary = _fcdtocp(fcd_datary);
00275     #endif
00276     if (datary == NULL) {
00277       printf("Massive catastrophe -- datary pointer is NULL\n");
00278       return -666;
00279     }
00280     #ifdef VERBOSE
00281       printf("file descriptor, datary = %d %d\n", *fdes, (int) datary);
00282     #endif
00283     count = (size_t) *no;
00284     jret = read(*fdes, (void *) datary, count);
00285     if (jret != *no) {
00286       #ifdef VERBOSE
00287         printf("did not read in the requested number of bytes\n");
00288         printf("read in %d bytes instead of %d \n",jret, *no);
00289       #endif
00290     }  
00291     else {
00292     #ifdef VERBOSE
00293       printf("read in %d bytes requested \n", *no);
00294     #endif
00295     }
00296     *nactual = jret;
00297     *newpos = *start + jret;
00298   }
00299 /* Done with reading */
00300  
00301 /* See if we should be writing */
00302   if ( BAWRITE & *mode && BAOPEN_RONLY & *mode ) {
00303     #ifdef VERBOSE
00304       printf("Trying to write on a read only file \n");
00305     #endif
00306      return -7;
00307   }
00308   else if ( BAWRITE & *mode ) {
00309     if (! (*mode & NOSEEK) ) {
00310       seekret = lseek(*fdes, *start, SEEK_SET);
00311       if (seekret == -1) {
00312       #ifdef VERBOSE
00313         printf("error in seeking to %d\n",*start);
00314       #endif
00315         return -8;
00316       }
00317     }
00318     #ifdef CRAY90
00319       datary = _fcdtocp(fcd_datary);
00320     #endif
00321     if (datary == NULL) {
00322       printf("Massive catastrophe -- datary pointer is NULL\n");
00323       return -666;
00324     }
00325     #ifdef VERBOSE
00326       printf("write file descriptor, datary = %d %d\n", *fdes, (int) datary);
00327     #endif
00328     count = (size_t) *no;
00329     jret = write(*fdes, (void *) datary, count);
00330     if (jret != *no) {
00331     #ifdef VERBOSE
00332       printf("did not write out the requested number of bytes\n");
00333       printf("wrote %d bytes instead\n", jret);
00334     #endif
00335       *nactual = jret;
00336       *newpos = *start + jret;
00337     }
00338     else {
00339     #ifdef VERBOSE
00340        printf("wrote %d bytes \n", jret);
00341     #endif
00342        *nactual = jret;
00343        *newpos = *start + jret;
00344     }
00345   }
00346 /* Done with writing */
00347     
00348 
00349 /* Close file if requested */
00350   if (BACLOSE & *mode ) {
00351     jret = close(*fdes);
00352     if (jret != 0) { 
00353     #ifdef VERBOSE
00354       printf("close failed! jret = %d\n",jret);
00355     #endif
00356       return -9;
00357     }
00358   }
00359 /* Done closing */
00360 
00361 /* Check that if we were reading or writing, that we actually got what */
00362 /*  we expected, else return a -10.  Return 0 (success) if we're here  */
00363 /*  and weren't reading or writing */
00364   if ( (*mode & BAREAD || *mode & BAWRITE) && (*nactual != *no) ) {
00365     return -10;
00366   }
00367   else {
00368     return 0;
00369   }
00370 } 
00371 #ifdef CRAY90
00372   #include <fortran.h>
00373   int BANIO
00374          (int * mode, int * start, int *newpos, int * size, int * no, 
00375           int * nactual, int * fdes, _fcd fcd_fname, void *datary) { 
00376   char *fname;
00377   int namelen;
00378 #endif
00379 #ifdef HP
00380   int banio
00381          (int * mode, int * start, int *newpos, int * size, int * no, 
00382           int * nactual, int * fdes, const char *fname, char *datary, 
00383           int  namelen ) {
00384 #endif
00385 #ifdef SGI
00386   int banio_
00387          (int * mode, int * start, int *newpos, int * size, int * no, 
00388           int * nactual, int * fdes, const char *fname, char *datary, 
00389           int  namelen ) {
00390 #endif
00391 #ifdef LINUX
00392   int banio_
00393          (int * mode, int * start, int *newpos, int * size, int * no, 
00394           int * nactual, int * fdes, const char *fname, char *datary, 
00395           int  namelen ) {
00396 #else
00397 #ifdef MACINTOSH
00398   int banio_
00399     (int * mode, int * start, int *newpos, int * size, int * no,
00400      int * nactual, int * fdes, const char *fname, char *datary,
00401      int  namelen ) {
00402 #endif
00403 #endif
00404 #ifdef LINUXF90
00405   int BANIO
00406          (int * mode, int * start, int *newpos, int * size, int * no, 
00407           int * nactual, int * fdes, const char *fname, char *datary, 
00408           int  namelen ) {
00409 #endif
00410 #ifdef VPP5000
00411   int banio_
00412          (int * mode, int * start, int *newpos, int * size, int * no, 
00413           int * nactual, int * fdes, const char *fname, char *datary, 
00414           int  namelen ) {
00415 #endif
00416 #ifdef IBM4
00417   int banio
00418          (int * mode, int * start, int *newpos, int * size, int * no, 
00419           int * nactual, int * fdes, const char *fname, char *datary, 
00420           int  namelen ) {
00421 #endif
00422 #ifdef IBM8
00423   int64_t banio
00424          (int64_t * mode, int64_t * start, int64_t * newpos,
00425           int64_t * size, int64_t * no, 
00426           int64_t * nactual, int64_t * fdes, const char *fname,
00427           char *datary, 
00428           int64_t namelen ) {
00429 #endif
00430   int i, j, jret, seekret;
00431   char *realname, *tempchar;
00432   int tcharval;
00433 
00434 /* Initialization(s) */
00435   *nactual = 0;
00436 
00437 /* Check for illegal combinations of options */
00438   if (( BAOPEN_RONLY & *mode) &&
00439      ( (BAOPEN_WONLY & *mode) || (BAOPEN_WONLY_TRUNC & *mode) || (BAOPEN_WONLY_APPEND & *mode) ) ) {
00440      #ifdef VERBOSE
00441        printf("illegal -- trying to open both read only and write only\n");
00442      #endif
00443      return -1;
00444   }
00445   if ( (BAREAD & *mode ) && (BAWRITE & *mode) ) {
00446      #ifdef VERBOSE
00447        printf("illegal -- trying to both read and write in the same call\n");
00448      #endif
00449      return -2;
00450   }
00451 
00452 /* This section handles Fortran to C translation of strings so as to */
00453 /*   be able to open the files Fortran is expecting to be opened.    */
00454   #ifdef CRAY90
00455     namelen = _fcdlen(fcd_fname);
00456     fname   = _fcdtocp(fcd_fname);
00457   #endif
00458   if ( (BAOPEN_RONLY & *mode) || (BAOPEN_WONLY & *mode) || 
00459        (BAOPEN_WONLY_TRUNC & *mode) || (BAOPEN_WONLY_APPEND & *mode) ||
00460        (BAOPEN_RW & *mode) ) {
00461     #ifdef VERBOSE
00462       printf("Will be opening a file %s %d\n", fname, namelen); fflush(stdout);
00463       printf("Strlen %d namelen %d\n", strlen(fname), namelen); fflush(stdout);
00464     #endif
00465     realname = (char *) malloc( namelen * sizeof(char) ) ;
00466     if (realname == NULL) { 
00467       #ifdef VERBOSE
00468         printf("failed to mallocate realname %d = namelen\n", namelen);
00469         fflush(stdout);
00470       #endif
00471       return -3;
00472     }
00473     tempchar = (char *) malloc(sizeof(char) * 1 ) ;
00474     i = 0;
00475     j = 0;
00476     *tempchar = fname[i];
00477     tcharval = *tempchar;
00478     while (i == j && i < namelen ) {
00479        fflush(stdout); 
00480        if ( isgraph(tcharval) ) {
00481          realname[j] = fname[i];
00482          j += 1;
00483        }
00484        i += 1;
00485        *tempchar = fname[i];
00486        tcharval = *tempchar;
00487     }
00488     #ifdef VERBOSE
00489       printf("i,j = %d %d\n",i,j); fflush(stdout);
00490     #endif
00491     realname[j] = '\0';
00492   } 
00493    
00494 /* Open files with correct read/write and file permission. */
00495   if (BAOPEN_RONLY & *mode) {
00496     #ifdef VERBOSE
00497       printf("open read only %s\n", realname);
00498     #endif
00499      *fdes = open(realname, O_RDONLY , S_IRWXU | S_IRWXG | S_IRWXO );
00500   }
00501   else if (BAOPEN_WONLY & *mode ) {
00502     #ifdef VERBOSE
00503       printf("open write only %s\n", realname);
00504     #endif
00505      *fdes = open(realname, O_WRONLY | O_CREAT , S_IRWXU | S_IRWXG | S_IRWXO );
00506   }
00507   else if (BAOPEN_WONLY_TRUNC & *mode ) {
00508     #ifdef VERBOSE
00509       printf("open write only with truncation %s\n", realname);
00510     #endif
00511      *fdes = open(realname, O_WRONLY | O_CREAT | O_TRUNC , S_IRWXU | S_IRWXG | S_IRWXO );
00512   }
00513   else if (BAOPEN_WONLY_APPEND & *mode ) {
00514     #ifdef VERBOSE
00515       printf("open write only with append %s\n", realname);
00516     #endif
00517      *fdes = open(realname, O_WRONLY | O_CREAT | O_APPEND , S_IRWXU | S_IRWXG | S_IRWXO );
00518   }
00519   else if (BAOPEN_RW & *mode) {
00520     #ifdef VERBOSE
00521       printf("open read-write %s\n", realname);
00522     #endif
00523      *fdes = open(realname, O_RDWR | O_CREAT , S_IRWXU | S_IRWXG | S_IRWXO );
00524   }
00525   else {
00526     #ifdef VERBOSE
00527       printf("no openings\n");
00528     #endif
00529   }
00530   if (*fdes < 0) {
00531     #ifdef VERBOSE
00532       printf("error in file descriptor! *fdes %d\n", *fdes);
00533     #endif
00534     return -4;
00535   }
00536   else {
00537     #ifdef VERBOSE
00538       printf("file descriptor = %d\n",*fdes );
00539     #endif
00540   }
00541 
00542 
00543 /* Read data as requested */
00544   if (BAREAD & *mode &&
00545    ( (BAOPEN_WONLY & *mode) || (BAOPEN_WONLY_TRUNC & *mode) || (BAOPEN_WONLY_APPEND & *mode) ) ) {
00546     #ifdef VERBOSE
00547       printf("Error, trying to read while in write only mode!\n");
00548     #endif
00549     return -5;
00550   }
00551   else if (BAREAD & *mode ) {
00552   /* Read in some data */
00553     if (! (*mode & NOSEEK) ) {
00554       seekret = lseek(*fdes, *start, SEEK_SET);
00555       if (seekret == -1) {
00556         #ifdef VERBOSE
00557           printf("error in seeking to %d\n",*start);
00558         #endif
00559         return -6;
00560       }
00561       #ifdef VERBOSE
00562       else {
00563          printf("Seek successful, seek ret %d, start %d\n", seekret, *start);
00564       }
00565       #endif
00566     }
00567     jret = read(*fdes, datary, *no*(*size) );
00568     if (jret != *no*(*size) ) {
00569       #ifdef VERBOSE
00570         printf("did not read in the requested number of items\n");
00571         printf("read in %d items of %d \n",jret/(*size), *no);
00572       #endif
00573       *nactual = jret/(*size);
00574       *newpos = *start + jret;
00575     }  
00576     #ifdef VERBOSE
00577       printf("read in %d items \n", jret/(*size));
00578     #endif
00579     *nactual = jret/(*size);
00580     *newpos = *start + jret;
00581   }
00582 /* Done with reading */
00583  
00584 /* See if we should be writing */
00585   if ( BAWRITE & *mode && BAOPEN_RONLY & *mode ) {
00586     #ifdef VERBOSE
00587       printf("Trying to write on a read only file \n");
00588     #endif
00589      return -7;
00590   }
00591   else if ( BAWRITE & *mode ) {
00592     if (! (*mode & NOSEEK) ) {
00593       seekret = lseek(*fdes, *start, SEEK_SET);
00594       if (seekret == -1) {
00595       #ifdef VERBOSE
00596         printf("error in seeking to %d\n",*start);
00597       #endif
00598         return -8;
00599       }
00600       #ifdef VERBOSE
00601       else {
00602         printf("Seek successful, seek ret %d, start %d\n", seekret, *start);
00603       }
00604       #endif
00605     }
00606     jret = write(*fdes, datary, *no*(*size));
00607     if (jret != *no*(*size)) {
00608     #ifdef VERBOSE
00609       printf("did not write out the requested number of items\n");
00610       printf("wrote %d items instead\n", jret/(*size) );
00611     #endif
00612       *nactual = jret/(*size) ;
00613       *newpos = *start + jret;
00614     }
00615     else {
00616     #ifdef VERBOSE
00617        printf("wrote %d items \n", jret/(*size) );
00618     #endif
00619        *nactual = jret/(*size) ;
00620        *newpos = *start + jret;
00621     }
00622   }
00623 /* Done with writing */
00624     
00625 
00626 /* Close file if requested */
00627   if (BACLOSE & *mode ) {
00628     jret = close(*fdes);
00629     if (jret != 0) { 
00630     #ifdef VERBOSE
00631       printf("close failed! jret = %d\n",jret);
00632     #endif
00633       return -9;
00634     }
00635   }
00636 /* Done closing */
00637 
00638 /* Check that if we were reading or writing, that we actually got what */
00639 /*  we expected, else return a -10.  Return 0 (success) if we're here  */
00640 /*  and weren't reading or writing */
00641   if ( (*mode & BAREAD || *mode & BAWRITE) && (*nactual != *no) ) {
00642     return -10;
00643   }
00644   else {
00645     return 0;
00646   }
00647 }