ffio.h

Go to the documentation of this file.
00001 /* USMID @(#) clibinc/ffio.h    92.11   11/09/99 17:20:39 */
00002 
00003 
00004 /*
00005 
00006   Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
00007 
00008   This program is free software; you can redistribute it and/or modify it
00009   under the terms of version 2 of the GNU General Public License as
00010   published by the Free Software Foundation.
00011 
00012   This program is distributed in the hope that it would be useful, but
00013   WITHOUT ANY WARRANTY; without even the implied warranty of
00014   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00015 
00016   Further, this software is distributed without any warranty that it is
00017   free of the rightful claim of any third person regarding infringement 
00018   or the like.  Any license provided herein, whether implied or 
00019   otherwise, applies only to this software file.  Patent licenses, if 
00020   any, provided herein do not apply to combinations of this program with 
00021   other software, or any other product whatsoever.  
00022 
00023   You should have received a copy of the GNU General Public License along
00024   with this program; if not, write the Free Software Foundation, Inc., 59
00025   Temple Place - Suite 330, Boston MA 02111-1307, USA.
00026 
00027   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00028   Mountain View, CA 94043, or:
00029 
00030   http://www.sgi.com
00031 
00032   For further information regarding this notice, see:
00033 
00034   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00035 
00036 */
00037 
00038 /*
00039  *      FFIO definitions, macros, and prototypes
00040  */
00041 
00042 #ifndef _FFIO_H
00043 #define _FFIO_H
00044 
00045 #include <clibdefs.h>
00046 #include <sys/types.h>          /* ffc_stat_s structure field declarations */
00047 #include <cray/fortio.h>        /* unum_t typedef */
00048 #if defined(__mips)
00049 #include <aio.h>
00050 #elif defined(_LITTLE_ENDIAN)
00051 /* do not include pthread.h for little endian systems */
00052 #else
00053 #include <cray/libuni.h>        /* for _LIB_UMK, used in fflistreq declaration*/
00054 #endif
00055 
00056 /*
00057  * read/write record processing modes
00058  */
00059 #define PARTIAL 0
00060 #define FULL    1
00061 
00062 /*
00063  * Status values for sw_status
00064  */
00065 #define FFBSY   0
00066 #define FFCNT   1
00067 #define FFEOR   2
00068 #define FFEOF   3
00069 #define FFEOD   4
00070 #define FFBOD   5
00071 #define FFERR   6
00072 
00073 /*
00074  * Command codes for fffcntl calls
00075  *      Values: 0 -     reserved for FORTRAN 'get fio pointer'
00076  *              1-99    reserved for CRI built-in layers
00077  *              100-199 reserved for user layers
00078  *              200-299 reserved for site layers
00079  */
00080 #define FC_GETINFO      1
00081 #define FC_STAT         2
00082 #define FC_SETRECL      3
00083 #define FC_RECALL       4
00084 #define FC_ACPTBAD      5
00085 #define FC_SKIPBAD      6
00086 #define FC_GETTP        7
00087 #define FC_AUTOBAD      8
00088 #define FC_CHECKTP      9
00089 #define FC_ENDSP        10
00090 #define FC_STARTSP      11
00091 #define FC_CLOSEV       12
00092 #define FC_SETSP        13
00093 #define FC_ASPOLL       14      /* give recall a shot at cleanup, no wait */
00094 #define FC_SCRATCH      15      /* identify a file as a scratch file */
00095 #define FC_TSYNC        16      /* sync a tape file */
00096 #define FC_DUMPSTATS    17      /* dump intermediate layer statistics */
00097 #define FC_TPC_SDBSZ    18      /* change block size on ER90 */
00098 #define FC_IALLOC       19      /* bottom layer call ialloc */
00099 #define FC_GETLK        20      /* get file lock */
00100 #define FC_SETLK        21      /* set file lock */
00101 #define FC_SETLKW       22      /* set file lock wait */
00102 #define FC_FSTATFS      23      /* bottom layer call fstatfs */
00103 #define FC_DIOINFO      24      /* get direct info (IRIX only) */
00104 #define FC_CHECKEOV     25      /* check end-of-volume status (IRIX only) */
00105 #define FC_TSDATA       26      /* get tape status information (IRIX only) */
00106 
00107 /*
00108  * Mask bits for return word in FC_GETINFO fffcntl call
00109  */
00110 #define FFC_STRM        0x00000001      /* can handle stream I/O */
00111 #define FFC_REC         0x00000002      /* can handle records */
00112 #define FFC_WEOF        0x00000004      /* can represent EOF */
00113 #define FFC_WEOD        0x00000008      /* can represent EOD (all can do) */
00114 
00115 #define FFC_BKSP        0x00000010      /* can handle backspace */
00116 #define FFC_BKFIL       0x00000020      /* can handle backfile */
00117 #define FFC_SEEKA       0x00000040      /* can seek absolute */
00118 #define FFC_SEEKR       0x00000080      /* can seek relative */
00119 #define FFC_SEEKE       0x00000100      /* can seek to end */
00120 #define FFC_POSREC      0x00000200      /* can position by record number */
00121 #define FFC_POSFIL      0x00000400      /* can position by EOF mark */
00122 #define FFC_RWND        0x00000800      /* can rewind by seek(x,0,0) */
00123 
00124 #define FFC_FIXD        0x00001000      /* can do fixed len recs */
00125 #define FFC_VAR         0x00002000      /* can do variable len recs */
00126 #define FFC_BINARY      0x00004000      /* can do binary records */
00127 #define FFC_CODED       0x00008000      /* can do formatted records */
00128 
00129 #define FFC_RDM         0x00010000      /* can do random I/O (no trunc) */
00130 #define FFC_SEQ         0x00020000      /* can do sequential I/O */
00131 #define FFC_ASYNC       0x00040000      /* can do asynchronous I/O */
00132 #define FFC_WRTRUNC     0x00080000      /* write implies truncation */
00133 
00134 #define FFC_NOTRN       0x00100000      /* Does no transformation on data */
00135                                         /* hence, 'backdoor' ops can be OK */
00136 #define FFC_BCKDOOR     0x00200000      /* Can handle O_SSD flag on open call */
00137 #define FFC_SKIPBAD     0x00400000      /* Can skip bad data */
00138 #define FFC_NOCLOSE     0x00800000      /* Don't try to close layer on abort */
00139 #define FFC_CANLISTIO   0x01000000      /* The layer has a listio entry */
00140 #define FFC_CANSYLISTIO 0x02000000      /* The layer has a listio entry that  */
00141                                         /* is capable of limited listio */
00142 
00143 /*
00144  * Command codes for POS calls
00145  */
00146 #define FP_GETPOS       1       /* get position of file */
00147 #define FP_SETPOS       2       /* set position of file */
00148 #define FP_BSEEK        3       /* seek to bit position */
00149 #define FP_BKSP         4       /* back up one record (BACKSPACE) */
00150 #define FP_BKFIL        5       /* back up one file (BACKFILE) */
00151 #define FP_GETREC       6       /* Get current record number */
00152 #define FP_SETREC       7       /* Set position to specified record number */
00153 #define FP_SKIPF        8       /* Skip file (SKIPF) */
00154 #define FP_SETTP        9       /* set position of tape file (SETTP) */
00155 #define FP_POS0         10      /* "position to current position" */
00156 #define FP_RSEEK        11      /* relative seek */
00157 #define FP_SKIPTPMK     12      /* skip tape mark */
00158 #define FP_GABS         13      /* get absolute position */
00159 #define FP_SABS         14      /* set absolute position */
00160 #define FP_GETTAPEPOS   15      /* get tape position (IRIX only) */
00161 #define FP_SETTAPEPOS   16      /* set tape position (IRIX only) */
00162 
00163 /*
00164  * Codes used to indicate direction/meaning for some positioning requests
00165  */
00166 #define FP_TPOS_ABS     0       /* absolute */
00167 #define FP_TPOS_FORW    1       /* forward */
00168 #define FP_TPOS_BACK    2       /* backwards */
00169 
00170 /*
00171  * Argument values for FC_AUTOBAD fffcntl request
00172  */
00173 #define AUTO_SKIP       1       /* skip 1 block of bad data */
00174 #define AUTO_ACPT       2       /* accept bad data */
00175 #define AUTO_SKIPALL    3       /* skip all bad data */
00176 
00177 /*
00178  * Flag values for FC_SCRATCH fffcntl request status word.
00179  */
00180 #define SCR_SINGLELINK  1       /* file is regular and not a linked file */
00181 #define SCR_UNLINKED    2       /* an unlink() successfully deleted the file */
00182 #define SCR_NOFLUSH     4       /* ffclose() buffer flushing suppressed */
00183 
00184 /*
00185  * Return the I/O status from an operation.
00186  */
00187 #define FFSTAT(io_sw)           ((io_sw).sw_stat)
00188 
00189 /*
00190  *      Status return:  This structure is used in all internal calls to return
00191  *      status.  The first word is made compatible with the iosw for use
00192  *      with async I/O.
00193  */
00194 struct ffsw
00195         {
00196         unsigned int    sw_flag:1;
00197         unsigned int    sw_error:31;
00198 #ifdef  _UNICOS
00199         unsigned int    sw_count:32;
00200 #else
00201         ssize_t         sw_count;
00202 #endif
00203         unsigned int    sw_stat:16;     /* FFCNT, etc. */
00204 #if     defined(_WORD32) || defined(__mips) || defined(_LITTLE_ENDIAN)
00205         int             sw_user:32;     /* For user layer storage */
00206 #else
00207         int             sw_user:48;     /* For user layer storage */
00208 #endif
00209 #if     defined(_ADDR64) || defined(__mips) || defined(_LITTLE_ENDIAN)
00210         void            *sw_iptr;       /* pointer to layer data */
00211         void            *sw_sptr;       /* pointer to status chain, if used. */
00212 #else
00213         int             sw_iptr:32;     /* pointer to layer data */
00214         int             sw_sptr:32;     /* pointer to status chain, if used. */
00215 #endif
00216         int             sw_rsv1;        /* may need later.  Save space now */
00217 #ifdef  __mips
00218         aiocb_t         aiocbp;
00219 #endif
00220 #ifdef  _EXTRA_FFSW_STUFF
00221         _EXTRA_FFSW_STUFF               /* for internal Cray applications use */
00222 #endif
00223         };
00224 
00225 /*
00226  *      fffcntl FC_GETINFO structure
00227  */
00228 struct ffc_info_s
00229         {
00230         long    ffc_flags;      /* flag word */
00231         int     ffc_gran;       /* minimum granularity, no. bits in smallest */
00232                                 /* I/O possible. (bits/bytes/words) */
00233         int     ffc_reclen;     /* Record length (in bits) */
00234         int     ffc_fd;         /* Lowest level file desc, -1 if invalid */
00235         int     ffc_poslen:16;  /* GETPOS/SETPOS pos array length */
00236 #if     defined(_WORD32) || defined(__mips) || defined(_LITTLE_ENDIAN)
00237         int     unused1:16;     /* reserved */
00238 #else
00239         int     unused1:48;     /* reserved */
00240 #endif
00241         int     unused2;        /* reserved */
00242         };
00243 
00244 /*
00245  *      fffcntl FC_SKIPBAD or FC_ACPTBAD structure
00246  */
00247 struct ffc_baddata_s
00248         {
00249         int     ffc_termcnd;    /* position after handling bad data */
00250         int     ffc_blocks;     /* number of blocks skipped */
00251         int     ffc_bytes;      /* number of bytes accepted */
00252         int     ffc_maxflag;    /* 1 if maximum number of words to accept */
00253         int     ffc_maxwords;   /* maximum number of words to accept */
00254         long    ffc_uda;        /* address of area to store data */
00255         int     unused1;        /* reserved */
00256         int     unused2;        /* reserved */
00257         };
00258 
00259 /*
00260  *      fffcntl FC_GETTP structure
00261  */
00262 struct ffc_gettp_s
00263         {
00264         int     ffc_glen;       /* number of words to copy to ffc_pa */
00265         int     ffc_synch;      /* 1 = synch, 0 = do not. Only after write */
00266 #if     defined(__mips) || defined(_LITTLE_ENDIAN)
00267         long long       *ffc_pa;/* info copied here */
00268 #else
00269         long    *ffc_pa;        /* info copied here */
00270 #endif
00271         int     unused1;        /* reserved */
00272         int     unused2;        /* reserved */
00273         };
00274 
00275 /*
00276  *      fffcntl FC_CHECKTP structure
00277  */
00278 struct ffc_chktp_s
00279         {
00280         int     stat;           /* status of tape */
00281         int     libblk;         /* Number of blocks in library */
00282         int     unused1;        /* reserved */
00283         int     unused2;        /* reserved */
00284         };
00285 
00286 /*
00287  *      fffcntl FC_CHECKEOV structure
00288  */
00289 struct ffc_chkev_s
00290         {
00291         int     stat;           /* status of tape: 1 = at eov */
00292         int     bufblk;         /* Number of buffered whole blocks */
00293         size_t  bufbytes;       /* number of bytes unwritten from last record
00294                                    on the tape */
00295         int     unused1;        /* reserved */
00296         int     unused2;        /* reserved */
00297         };
00298         
00299 /*
00300  *      fffcntl FC_STAT structure
00301  *
00302  *      This is a copy of the stat structure defined in <sys/stat.h>.
00303  *      Matches stat structure for:
00304  *
00305  *                      UNICOS 8.0
00306  *                      UNICOS-MAX 1.0
00307  *                      Solaris 5.3
00308  */
00309 #ifdef  _UNICOS
00310 
00311 struct  ffc_stat_s
00312         {
00313         dev_t   st_dev;
00314         ino_t   st_ino;
00315         mode_t  st_mode;
00316         nlink_t st_nlink;
00317         uid_t   st_uid;
00318         gid_t   st_gid;
00319         dev_t   st_rdev;
00320         off_t   st_size;
00321         time_t  st_atime;
00322         long    st_spare1;              /* Reserved for microsec time stamps */
00323         time_t  st_mtime;
00324         long    st_spare2;              /* Reserved for microsec time stamps */
00325         time_t  st_ctime;
00326         long    st_spare3;              /* Reserved for microsec time stamps */
00327         _SHORTPAD
00328         unsigned short  st_acid;        /* Accounting id */
00329 #if     defined(_CRAY1) || defined(_CRAYMPP)
00330         long    st_count;               /* Reference count */
00331         off_t   st_msize;               /* Modification size for signature */
00332 #endif /* _CRAY1 || _CRAYMPP */
00333         unsigned int st_msref : 1,      /* Modification signature referenced */
00334                      st_ms    :31,      /* Modification signature */
00335                      st_gen   :32;      /* Generation number */
00336 #if     defined(_CRAY1) || defined(_CRAYMPP)
00337 /*18*/
00338         long    st_blocks;              /* #of sectors allocated to file */
00339         long    st_blksize;             /* Optimal small I/O xfer size (bytes)*/
00340         long    st_oblksize;            /* Optimal large I/O xfer size (bytes)*/
00341         long    st_allocf;              /* Allocation flags */
00342         long    st_cblks;               /* Cluster blocks (Cray-YMP) */
00343         long    st_cbits;               /* Cluster bits */
00344         long    st_param[8];            /* 8-pack track/sector addresses */
00345         long    st_spareparam[4];       /* Reserved for additional pack */
00346 #endif /* _CRAY1 || _CRAYMPP */
00347 /*36*/
00348         /* data migration fields */
00349         _SHORTPAD
00350         unsigned short  st_dm_mode;     /* actual file mode */
00351         unsigned int
00352                 st_dm_port  : 3,        /* migrated file daemon port */
00353                 st_dm_state : 5,        /* migrated file state */
00354                 st_dm_status: 56;       /* migrated file status flags */
00355         long    st_dm_mid;              /* migrated file machine id */
00356         long    st_dm_key;              /* migrated file key */
00357 
00358 /*40*/
00359         /* security fields */
00360         unsigned int        : 62,
00361                 st_hasacl   : 1,        /* File has an ACL */
00362                 st_hascomps : 1;        /* File has compartments */
00363         _SHORTPAD
00364         short   st_slevel;              /* file level */
00365         _SHORTPAD
00366         short   st_secflg;              /* security flags */
00367         _SHORTPAD
00368         short   st_intcls;              /* integrity class */
00369         _SHORTPAD
00370         short   st_intcat;              /* integrity category */
00371 
00372 /*45*/
00373         long    st_site;                /* site field from inode */
00374         long    st_nindir;              /* # of indirect extent blocks */
00375         long    st_resv_pad[6];         /* reserved pad space to 53 words */
00376         };
00377 
00378 #elif   defined(_SOLARIS)
00379 
00380 #include <sys/time.h>
00381 
00382 struct  ffc_stat_s {
00383         dev_t   st_dev;
00384         long    st_pad1[3];
00385         ino_t   st_ino;
00386         mode_t  st_mode;
00387         nlink_t st_nlink;
00388         uid_t   st_uid;
00389         gid_t   st_gid;
00390         dev_t   st_rdev;
00391         long    st_pad2[2];
00392         off_t   st_size;
00393         long    st_pad3;
00394         timestruc_t st_atim;
00395         timestruc_t st_mtim;
00396         timestruc_t st_ctim;
00397         long    st_blksize;
00398         long    st_blocks;
00399         char    st_fstype[16 /* == _ST_FSTYPSZ */ ];
00400         long    st_pad4[8];
00401         };
00402 
00403 #elif   defined(__mips)
00404 #include <sys/stat.h>
00405 #ifdef  _TIMESTRUCT_T
00406 #define _TIMESTRUCT_FFIO timestruct_t
00407 #else
00408 #define _TIMESTRUCT_FFIO timespec_t
00409 #endif
00410 struct  ffc_stat_s {
00411         dev_t   st_dev;
00412         long    st_pad1[3];     /* reserved for network id */
00413         ino_t   st_ino;
00414         mode_t  st_mode;
00415         nlink_t st_nlink;
00416         uid_t   st_uid;
00417         gid_t   st_gid;
00418         dev_t   st_rdev;
00419         long    st_pad2[2];     /* dev and off_t expansion */
00420         off_t   st_size;
00421         long    st_pad3;        /* future off_t expansion */
00422         _TIMESTRUCT_FFIO st_atim;
00423         _TIMESTRUCT_FFIO st_mtim;
00424         _TIMESTRUCT_FFIO st_ctim;
00425         long    st_blksize;
00426         blkcnt_t st_blocks;
00427         char    st_fstype[_ST_FSTYPSZ];
00428         long    st_pad4[8];     /* expansion area */
00429 };
00430 #elif   defined(_LITTLE_ENDIAN)
00431 #include <sys/stat.h>
00432 #ifdef _LP64
00433 struct  ffc_stat_s {
00434         dev_t   st_dev;
00435         ino_t   st_ino;
00436         nlink_t st_nlink;
00437         mode_t  st_mode;
00438         uid_t   st_uid;
00439         gid_t   st_gid;
00440         int     pad0;
00441         dev_t   st_rdev;
00442         off_t   st_size;
00443         time_t  st_atim;
00444         long int __reserved0;
00445         time_t  st_mtim;
00446         long int __reserved1;
00447         time_t  st_ctim;
00448         long int __reserved2;
00449         unsigned long   st_blksize;
00450         blkcnt_t        st_blocks;
00451         unsigned long   unused1[1];
00452         unsigned long   unused2[1];
00453         unsigned long   unused3[1];
00454         };
00455 #else
00456 struct  ffc_stat_s {
00457         dev_t   st_dev;
00458         unsigned short  st_pad1[1];
00459         ino_t   st_ino;
00460         mode_t  st_mode;
00461         nlink_t st_nlink;
00462         uid_t   st_uid;
00463         gid_t   st_gid;
00464         dev_t   st_rdev;
00465         unsigned short  st_pad2[1];
00466         off_t   st_size;
00467         unsigned long   st_blksize;
00468         blkcnt_t        st_blocks;
00469         time_t  st_atim;
00470         unsigned long   unused1[1];
00471         time_t  st_mtim;
00472         unsigned long   unused2[1];
00473         time_t  st_ctim;
00474         unsigned long   unused3[1];
00475         unsigned long   unused4[1];
00476         unsigned long   unused5[1];
00477         };
00478 #endif /* _LP64 */
00479 
00480 #endif  /* __mips */
00481 
00482 /*
00483  *      fffcntl FC_IALLOC structure
00484  */
00485 struct ff_ialloc_struct 
00486         {
00487         long    ia_nb;
00488         int     ia_flag;
00489         int     ia_part;
00490         int     ia_avl;
00491         int     ia_ret;
00492         int     ia_before;
00493         };
00494 /*
00495  *      FP_SKIPF structure
00496  */
00497 struct ffp_skipf_s
00498         {
00499         int     ffp_nfil;       /* number of files to skip (input and output) */
00500         int     ffp_nrec;       /* number of records skipped (optional output)*/
00501         };
00502 
00503 /*
00504  *      FP_SETTP structure
00505  */
00506 struct ffp_settp_s
00507         {
00508         int             ffp_nbs_p;      /* forward, backward or absolute nb */
00509         long            ffp_nb;         /* number of blocks (always positive) */
00510         int             ffp_nvs_p;      /* forward, backward or absolute nv */
00511         int             ffp_nv;         /* number of volumes (always positive) */
00512 #if     defined(__mips)
00513         __int64_t       ffp_vi;         /* volume identifier */
00514 #elif   defined(_LITTLE_ENDIAN)
00515         long long       ffp_vi;         /* volume identifier */
00516 #else
00517         long            ffp_vi;         /* volume identifier */
00518 #endif
00519         int             unused1;        /* reserved */
00520         int             unused2;        /* reserved */
00521         };
00522         
00523 /*
00524  *      FP_SKIPTPMK structure
00525  */
00526 struct ffp_skiptpmk_s
00527         {
00528         int     ffp_ntpmk;      /* number of tpmks to skip (input and output) */
00529         int     unused1;        /* reserved */
00530         };
00531 
00532 /*
00533  *      FP_GABS and FP_SABS structure
00534  */
00535         struct ffp_abs
00536         {
00537 #if defined(__mips)
00538         __int64_t       ffp_absaddr;
00539 #elif   defined(_LITTLE_ENDIAN)
00540         long long       ffp_absaddr;
00541 #else
00542         long    ffp_absaddr;
00543 #endif
00544         int     ffp_partition;
00545         int     ffp_filesec;
00546         int     ffp_datablock;
00547         };
00548 
00549 /*
00550  *      FP_GETTAPEPOS and FP_SETTAPEPOS structures
00551  */
00552         struct ffp_tapepos
00553         {
00554         int     ffp_type;
00555         int     ffp_blockno;
00556 #if     defined(__mips)
00557         __int64_t       ffp_vsn;
00558 #elif   defined(_LITTLE_ENDIAN)
00559         long long       ffp_vsn;
00560 #else
00561         long    ffp_vsn;
00562 #endif
00563         int     ffp_resvd[4];
00564         };
00565 
00566 /*
00567  *      fflistio request structure, similar to def in <sys/listio.h>
00568  */
00569 
00570 #if     defined(__mips) || defined(_LITTLE_ENDIAN)
00571 struct  fflistreq
00572         {
00573         int     li_opcode;              /* operation code */
00574         int     li_drvr:32,             /* driver dependent */
00575                 li_flags:32;            /* request flags */
00576         off_t   li_offset;              /* starting byte offset */
00577         int     li_fildes;              /* file descriptor (returned by ffopen)*/
00578         char    *li_buf;                /* buffer address */
00579         size_t  li_nbyte;               /* bytes per stride count */
00580         struct ffsw *li_status;         /* status structure */
00581         int     li_signo;               /* signal to send upon completion */
00582         int     li_nstride;             /* number of strides */
00583         off_t   li_filstride;           /* file stride length in bytes */
00584         size_t  li_memstride;           /* buffer stride length in bytes */
00585         struct fdinfo *li_ffioptr;      /* for use by library routines */
00586         };
00587 #else
00588 struct  fflistreq
00589         {
00590         int     li_opcode;              /* operation code */
00591         int     li_drvr:32,             /* driver dependent */
00592                 li_flags:32;            /* request flags */
00593         long    li_offset;              /* starting byte offset */
00594         int     li_fildes;              /* file descriptor (FFIO pointer) */
00595         char    *li_buf;                /* buffer address */
00596         long    li_nbyte;               /* bytes per stride count */
00597         struct ffsw *li_status;         /* status structure */
00598         int     li_signo;               /* signal to send upon completion */
00599         int     li_nstride;             /* number of strides */
00600         long    li_filstride;           /* file stride length in bytes */
00601         long    li_memstride;           /* buffer stride length in bytes */
00602 #ifdef  _LIB_UMK
00603 #ifndef _CRAY1
00604         int     li_remote_vpe;          /* distio vpe number */
00605         int     li_pad[3];              /* mpp extensions */
00606 #endif
00607 #endif
00608         };
00609 #endif
00610 
00611 #ifdef  _LIB_INTERNAL           /* defs below are not for user consumption */
00612 
00613 #include <cray/portdefs.h>
00614 
00615 #ifndef _TRUE
00616 #define _TRUE 1
00617 #endif
00618 #ifndef _FALSE
00619 #define _FALSE 0
00620 #endif
00621 
00622 #define NO      0
00623 #define NONE    0
00624 #define YES     1       /* it is important that this is 1 */
00625 
00626 /*
00627  * Change this anytime the format of the environment variables changes.
00628  */
00629 #define ASG_VERSION 1
00630 
00631 #if     defined(_WORD32) || defined(__mips) || defined(_LITTLE_ENDIAN)
00632 #define MAGIC_ID 0x2d464443     /* '-FDC' only 4 chars per int */
00633 #else
00634 #define MAGIC_ID '--*FDC--'
00635 #endif
00636 
00637 /*
00638  * The following is a macro to change a CAL symbol declaration into a
00639  * value usable by C.
00640  */
00641 #define _VALUE(xtern)   ((int)(&(xtern)))
00642 
00643 /*
00644  * General directions
00645  *      These are the constants that are used to keep track of the state of
00646  *      the I/O.
00647  */
00648 #define READIN  1       /* last op was READ */
00649 #define WRITIN  2       /* last op was WRITE */
00650 #define POSITIN 4       /* last op was POSITION */
00651 
00652 /*
00653  * Record Translation classes
00654  *      Note: All of the conversion types for IBM and VMS can be grouped into
00655  *      two classes.  The Fixed length record type, and the Variable
00656  *      length record type.  These types differ within the broad
00657  *      group according to the existence of blocking, control words,
00658  *      and padding.
00659  *
00660  * When adding new classes, be sure to look in libu/ffio/fxrmisc.c and update
00661  *      ownopen[] and in fxrmain.c update _recfm_tab[]
00662  */
00663 #define CLASS_END       0       /* End of chain marker. This is a dummy layer */
00664                                 /* that is always tacked on the end of spec. */
00665                                 /* It selects an appropriate handler. */
00666                                 /* depending on the device. */
00667 #define CLASS_SYSCALL   1       /* handlers for UNIX/stream record model */
00668 #define CLASS_NULL      2       /* explicit NULL layer, does nothing */
00669 #define CLASS_SYSTEM    3       /* same as End of Chain, above */
00670 #define CLASS_COS       4       /* COS blocking */
00671 #define CLASS_BMX       5       /* TAPE handlers */
00672 #define CLASS_F         6       /* FIXED length, no control words */
00673 #define CLASS_V         7       /* variable length, control words */
00674                                 /* as prefixes only */
00675 #define CLASS_TEXT      8       /* records terminated by 'special character' */
00676 #define CLASS_X         9       /* records with control words as both */
00677                                 /* prefix and suffix on each record */
00678 #define CLASS_CDC       10      /* CDC class */
00679 #define CLASS_SDS       11      /* SDS handlers */
00680 #define CLASS_MR        12      /* memory resident layer */
00681 #define CLASS_TRACE     13      /* TRACE handlers.  Debug tool for 1 file */
00682 #define CLASS_USER      14
00683 #define CLASS_SITE      15
00684 #define CLASS_ERROR     16      /* error layer */
00685 #define CLASS_FD        17      /* user specified file descriptor */
00686 #define CLASS_BLX       18      /* blank expand/compress layer */
00687 #define CLASS_CACHE     19      /* cache layer */
00688 #define CLASS_ER90B     20      /* ER90 byte-stream layer */
00689 #define CLASS_BUFA      21      /* bufa layer */
00690 #define CLASS_CACHEA    22      /* cachea layer */
00691 #define CLASS_EVENT     23      /* event layer */
00692 #define CLASS_LOCK      24      /* lock layer - CRI internal use */
00693 #define CLASS_GLOBAL    25      /* global layer (mpp systems only) */
00694 #define CLASS_F77       26      /* f77 layer */
00695 #define CLASS_TMF       27      /* tmf layer */
00696 #define CLASS_CMP       28      /* compression layer */
00697 
00698 #define CLASS_USER0     30
00699 #define CLASS_USER1     31
00700 #define CLASS_USER2     32
00701 #define CLASS_USER3     33
00702 #define CLASS_USER4     34
00703 #define CLASS_USER5     35
00704 #define CLASS_USER6     36
00705 #define CLASS_USER7     37
00706 #define CLASS_USER8     38
00707 #define CLASS_USER9     39
00708 
00709 #define NUM_CLASSES     40
00710 
00711 /*
00712  * Get definitions of error numbers.
00713  */
00714 #include <liberrno.h>
00715 
00716 /*
00717  * Status returns
00718  */
00719 #define ERR     -1
00720 
00721 /*
00722  * ===== Define operation(s) on bit pointers =====
00723  */
00724 
00725 /*
00726  * typedefs
00727  */
00728 
00729 /*
00730  * The bitptr is the basic pointer for use by the FDC routines.
00731  *
00732  * For CRAY-2 and CX/CEA machines, it is a word pointer shifted
00733  * left 6 bits, with the bit offset in the lower 6 bits.
00734  *
00735  * For the CRAY-T3D, CRAY-T3E, and MIPS 64-bit architectures it is a character
00736  * pointer shifted left 3 bits, with the bit offset in the lower 3 bits.
00737  *
00738  * For 32-bit architectures, it is a 64 bit word that is a 32 bit
00739  * character pointer shifted left 3 bits, with the bit offset in
00740  * the lower 3 bits.
00741  *
00742  * Note that LP is LONG and POINTER are 64 bits on some systems.
00743  */
00744 
00745 #ifdef  __mips
00746 typedef __int64_t bitptr;       
00747 #elif   defined(_WORD32)
00748 typedef long long bitptr;
00749 #elif   defined(_LITTLE_ENDIAN) && defined(_LP64)
00750 typedef long bitptr;
00751 #else
00752 typedef long bitptr;
00753 #endif
00754 
00755 /*
00756  * GET_BPTR()
00757  *      Get the raw value of a bit pointer into a word.
00758  */
00759 #define GET_BPTR(value,bit_ptr) (value) = (bit_ptr)
00760 
00761 /*
00762  * SET_BPTR()
00763  *      Set a bit pointer to a value
00764  */
00765 #define SET_BPTR(bit_ptr,value) (bit_ptr) = (value)
00766 
00767 /*
00768  * INC_BPTR()
00769  *      increment a bit pointer.
00770  */
00771 #define INC_BPTR(bit_ptr,inc)   ((bitptr)(bit_ptr) + (bitptr)(inc))
00772 
00773 /*
00774  * SUBT_BPTR(bptr1, bptr2)
00775  *      Subtract bptr2 from bptr1 and return a number of bits
00776  */
00777 #define SUBT_BPTR(bptr1, bptr2) ((bitptr)(bptr1) - (bitptr)(bptr2))
00778 
00779 /*
00780  * BPTR2WP()
00781  *      Convert a bit pointer to a C word pointer
00782  *
00783  *      Retain virtual region number in bits 63 to 61.
00784  */
00785 #if     (defined(_LITTLE_ENDIAN) && defined(_LP64))
00786 #define BPTR2WP(bptr)           ((long *)(((((long)(bptr) << 3) >> 6) & 0x1ffffffffffffff8L) | ((long)(bptr) & 0xe000000000000000L)))
00787 #elif   defined(_WORD32)
00788 #define BPTR2WP(bptr)           ((long *)(((long)((bitptr)(bptr) >> 3)) & ~0x3))
00789 #elif   defined (_CRAYMPP) || (_MIPS_SZLONG == 64)
00790 #define BPTR2WP(bptr)           ((long *)(((long)(bptr) >> 3) & ~0x7))
00791 #else
00792 #define BPTR2WP(bptr)           ((long *)((long)(bptr) >> 6))
00793 #endif
00794 
00795 /*
00796  * BPTR2CP()
00797  *      Convert a bit pointer to a C character pointer
00798  *
00799  *      Retain virtual region number in bits 63 to 61.
00800  */
00801 #if     (defined(_LITTLE_ENDIAN) && defined(_LP64))
00802 #define BPTR2CP(bptr)           ((char *)(((long)(((long)(bptr) << 3) >> 6) & 0x1fffffffffffffffL) | ((long)(bptr) & 0xe000000000000000L)))
00803 #elif   defined (_CRAYMPP) || defined (_WORD32) || defined(__mips)
00804 #define BPTR2CP(bptr)           ((char *)((long)((bitptr)(bptr) >> 3)))
00805 #else
00806 #define BPTR2CP(bptr) \
00807         ((char *)(_dshiftr((long)(bptr), (long)(bptr), 6) & 0xe3ffffffffffffff))
00808 #endif
00809 
00810 /*
00811  * WPTR2BP()
00812  *      Convert a C word pointer to a bit ptr
00813  *
00814  *      Retain virtual region number in bits 63 to 61.
00815  */
00816 #if     (defined(_LITTLE_ENDIAN) && defined(_LP64))
00817 #define WPTR2BP(wp)             ((long)(((((long)((char *)(wp))) & 0x03ffffffffffffffL) << 3) | ((long)((char *)(wp)) & 0xe000000000000000L)))
00818 #elif   defined (_CRAYMPP) || defined (_WORD32) || defined(__mips)
00819 #define WPTR2BP(wp)             (((bitptr)((long)((char *)(wp)))) << 3)
00820 #else
00821 #define WPTR2BP(wp)             ((long)(((long)((char *)(wp))) << 6))
00822 #endif
00823 
00824 /*
00825  * CPTR2BP()
00826  *      Convert a C character pointer to a bit ptr
00827  *
00828  *      Retain virtual region number in bits 63 to 61.
00829  */
00830 #if     (defined(_LITTLE_ENDIAN) && defined(_LP64))
00831 #define CPTR2BP(cptr)           ((bitptr)(((((long)((char *)(cptr))) & 0x03ffffffffffffffL) << 3) | ((long)((char *)(cptr)) & 0xe000000000000000L)))
00832 #elif   defined (_CRAYMPP) || defined (_WORD32) || defined(__mips)
00833 #define CPTR2BP(cptr)           (((bitptr)(long)(char *)(cptr)) << 3)
00834 #else
00835 #define CPTR2BP(cptr)           ((long)_dshiftl((long)(cptr), (long)(cptr), 6))
00836 #endif
00837 
00838 /*
00839  * BPTR2DWP()
00840  *      Convert a bit ptr to a 64-bit-word ptr
00841  *
00842  *      Retain virtual region number in bits 63 to 61.
00843  */
00844 #if     (defined(_LITTLE_ENDIAN) && defined(_LP64))
00845 #define BPTR2DWP(bptr)           ((long *)(((((long)(bptr) << 3) >> 6) & ~0x7) | ((long)(bptr) & 0xe000000000000000L)))
00846 #elif   defined(_WORD32)
00847 #define BPTR2DWP(bptr)          ((long *)(((long)((bitptr)(bptr) >> 3)) & ~0x7))
00848 #elif   defined (_CRAYMPP) || (_MIPS_SZLONG == 64)
00849 #define BPTR2DWP(bptr)           ((long *)(((long)(bptr) >> 3) & ~0x7))
00850 #else
00851 #define BPTR2DWP(bptr)          ((long *)((long)(bptr) >> 6))
00852 #endif
00853 
00854 /*
00855  * BPBITOFF(bitptr)
00856  *      Return the bit offset within the current word.
00857  */
00858 #ifdef  _WORD32 
00859 #define BPBITOFF(bptr)          (long) ((bitptr)(bptr) & 0x1fLL)
00860 #else
00861 #define BPBITOFF(bptr)          ((long)(bptr) & 0x3f)
00862 #endif
00863 
00864 /*
00865  * BPDWBITOFF(bitptr)
00866  *      Return the bit offset within the current 64-bit word.
00867  */
00868 #ifdef  _WORD32
00869 #define BPDWBITOFF(bptr)          (long) ((bitptr)(bptr) & 0x3fLL)
00870 #else
00871 #define BPDWBITOFF(bptr)          ((long)(bptr) & 0x3f)
00872 #endif
00873 
00874 /*
00875  * NUMARG()
00876  *      Get the number of words passed in the argument list of the current
00877  *      function.
00878  */
00879 #ifdef  _UNICOS
00880 #define NUMARG(x)       x = _numargs()
00881 #endif
00882 
00883 /*
00884  * Get the IO info block for a file descriptor
00885  */
00886 #if     !defined(__mips) && !defined(_LITTLE_ENDIAN)
00887 #define GETIOB(x) (struct fdinfo *)(x)
00888 #else
00889 extern struct fdinfo *_cnvrt2fdinfo(int _fd);
00890 #define GETIOB(x) _cnvrt2fdinfo(x)
00891 #endif
00892 
00893 /*
00894  * XRCALL is a simple macro that allows control of the mechanism that
00895  * handles the function pointer references.  It also allows us to
00896  * insert debugging code at build time.
00897  */
00898 #if     defined(DEBUG) && !defined(__mips) && !defined(_LITTLE_ENDIAN)
00899 #define XRCALL(fio,ptrname)     _xrtrace((fio), (fio)->xr.ptrname,#ptrname,
00900 #else
00901 #define XRCALL(fio,ptrname)     (fio)->xr.ptrname(
00902 #endif
00903 /*
00904  * Add check for fdinfo pointer.
00905  */
00906 #define CHECK_FIOPTR(fio, stat)                                         \
00907                 {                                                       \
00908                 if (fio == (struct fdinfo *)0L || fio == (struct fdinfo *)-1L || \
00909                         fio->magic != MAGIC_ID)                         \
00910                         {                                               \
00911                         errno = FDC_ERR_BADPTR;                         \
00912                         ERETURN(stat, FDC_ERR_BADPTR, 0);               \
00913                         }                                               \
00914                 }
00915 
00916 /*
00917  * Debugging stuff
00918  */
00919 #define FDCTRACE(bit) ((__fdctrace_enable & (bit)) != 0)
00920 
00921 /*
00922  * bit defines for debug output
00923  */
00924 #define TRACE_CALLS     0x001
00925 #define TRACE_STATUS    0x002
00926 #define TRACE_ASG       0x004
00927 #define TRACE_OPEN      0x008
00928 #define TRACE_COS       0x010
00929 #define TRACE_SDSIO     0x020
00930 #define TRACE_WA        0x040
00931 #define TRACE_CACHE     0x080
00932 #define TRACE_SYS       0x100
00933 
00934 /*
00935  * IS_RESERVED_FC evaluates to:
00936  *      1 if the fffcntl function code is one reserved for site or user layers.
00937  *      0 otherwise.
00938  */
00939 #define IS_RESERVED_FC(x)       (100 <= (x) && (x) <= 299)
00940 
00941 /*
00942  * DUMP_IOB dumps out the IOB in human readable format for
00943  * debugging.  It is conditionally compiled and is a no-op
00944  * in normal use.
00945  */
00946 #if     defined(DEBUG) && !defined(__mips) && !defined(_LITTLE_ENDIAN)
00947 #define DUMP_IOB(fio)                                                   \
00948         {                                                               \
00949         if (FDCTRACE(TRACE_OPEN))                                       \
00950                 {                                                       \
00951                 _xrt_putf("DUMP_IOB: fio=%o B %d - rfd=%o B %d, nfio=%o\n",\
00952                         fio, fio, (fio)->realfd, (fio)->realfd,         \
00953                         (fio)->fioptr);                                 \
00954                 _xrt_putf("DUMP_IOB:\trtype=%d, mxr=%d, mbs=%d\n",      \
00955                         (fio)->rtype,                                   \
00956                         (fio)->maxrecsize, (fio)->maxblksize);          \
00957                 _xrt_putf("DUMP_IOB:\tbase=%o, bufsize=%o\n",           \
00958                         (fio)->_base, (fio)->_ffbufsiz);                \
00959                 }                                                       \
00960         }
00961 
00962 #define GTRACEBACK()    TRBK()
00963 
00964 #define EQ ==
00965 #define NE !=
00966 #define LT <
00967 #define GT >
00968 #define LE <=
00969 #define GE >=
00970 #define SANITYCHK(aarg,rel,bbarg)                                       \
00971                 if (aarg rel bbarg)                                     \
00972                         {                                               \
00973                         _xrt_putf("SANITY CHECK: %s %s %s !!\n",        \
00974                                 #aarg, #rel, #bbarg);                   \
00975                         _xrt_putf("%s=%d %16x, %s=%d %16x\n",           \
00976                                 #aarg,aarg,aarg,#bbarg,bbarg,bbarg);    \
00977                         GTRACEBACK();                                   \
00978                         exit(1);                                        \
00979                         }
00980 
00981 #define BUFCHK(fio,bits)                                                \
00982                         {                                               \
00983                         char *BCXbuflim, *BCXcurdat, *BCXptr, *BCXbase; \
00984                                                                         \
00985                         BCXbase = BPTR2CP((fio)->_base);                \
00986                         BCXptr = BPTR2CP((fio)->_ptr);                  \
00987                         SANITYCHK(BCXptr,LT,BCXbase);                   \
00988                         BCXbuflim = BPTR2CP((fio)->_base) + (fio)->_ffbufsiz; \
00989                         BCXcurdat = BPTR2CP((fio)->_ptr) + ((bits) >> 3); \
00990                         SANITYCHK(BCXcurdat,GT,BCXbuflim);              \
00991                         }
00992                         
00993 #else
00994 #define DUMP_IOB(fio)           /* no-op */
00995 #define SANITYCHK(a,rel,b)      /* no-op */
00996 #define BUFCHK(fio,bits)        /* no-op */
00997 #endif
00998 
00999 /*
01000  * READBLK()
01001  *      Read one block from the next lower layer.
01002  *      Data is read in at fio->_ptr.
01003  */
01004 #define READBLK(retval,fio,nbytes,stat,fulp,ubc)                        \
01005                         {                                               \
01006                         struct fdinfo *RBllfio;                         \
01007                                                                         \
01008                         SANITYCHK((nbytes),LT,0);                       \
01009                         RBllfio = (fio)->fioptr;                        \
01010                         retval = XRCALL(RBllfio,readrtn)                \
01011                                         (RBllfio), /* fd of nxt lvl */  \
01012                                         (fio)->_ptr,                    \
01013                                         (nbytes),                       \
01014                                         (stat),                         \
01015                                         (fulp),                         \
01016                                         (ubc));                         \
01017                         (fio)->_cnt = 0;                                \
01018                         if (retval > 0)                                 \
01019                                 {                                       \
01020                                 (fio)->_cnt = (retval << 3) - *(ubc);   \
01021                                 }                                       \
01022                         }
01023 
01024 /*
01025  * WRITEBLK()
01026  *      Write one block from the buffer to the next lower layer
01027  */
01028 #define WRITEBLK(retval,fio,nbytes,stat,fulp,ubc)                       \
01029                         {                                               \
01030                         struct fdinfo *WBllfio;                         \
01031                                                                         \
01032                         SANITYCHK((nbytes),LT,0);                       \
01033                         WBllfio = (fio)->fioptr;                        \
01034                         retval = XRCALL(WBllfio, writertn)              \
01035                                         (WBllfio),/* fd of nxt lvl */   \
01036                                         (fio)->_base, /* addr of buf */ \
01037                                         (nbytes),                       \
01038                                         (stat),                         \
01039                                         (fulp),                         \
01040                                         (ubc));                         \
01041                         if ((retval) >= 0)                              \
01042                                 {                                       \
01043                                 (fio)->_cnt = 0;                        \
01044                                 (fio)->_ptr = (fio)->_base;             \
01045                                 (fio)->segbits = 0;                     \
01046                                 }                                       \
01047                         }
01048 
01049 /*
01050  * SKIP_BITS()
01051  * on reading, skip the given number of bits by adjusting counters
01052  */
01053 #define SKIP_BITS(xfio,xnbits)                                          \
01054                                 {                                       \
01055                                 register int SKBtemp;                   \
01056                                 SKBtemp = (xnbits);                     \
01057                                 SET_BPTR((xfio)->_ptr,                  \
01058                                         INC_BPTR((xfio)->_ptr,SKBtemp)); \
01059                                 (xfio)->segbits -= SKBtemp;             \
01060                                 (xfio)->_cnt -= SKBtemp;                \
01061                                 }
01062 
01063 /*
01064  * Get data from buffer and update pointers
01065  */
01066 #define GETDATA(bufptr, xfio, xnbits)                           \
01067                         {                                       \
01068                         register int GTDtemp;                   \
01069                         GTDtemp = (xnbits);                     \
01070                         BUFCHK((xfio),(GTDtemp));               \
01071                         MOV_BITS((bufptr), (xfio)->_ptr, (GTDtemp)); \
01072                         SKIP_BITS((xfio),(GTDtemp));            \
01073                         }
01074 
01075 /*
01076  * Put the data in the buffer from the UDA
01077  */
01078 #define PUTDATA(bufptr, xfio, xnbits)                           \
01079                         {                                       \
01080                         register long PTDtemp;                  \
01081                         PTDtemp = (xnbits);                     \
01082                         BUFCHK((xfio),(PTDtemp));               \
01083                         MOV_BITS((xfio)->_ptr, (bufptr), (PTDtemp)); \
01084                         SET_BPTR((xfio)->_ptr,                  \
01085                                 INC_BPTR((xfio)->_ptr,(PTDtemp))); \
01086                         (xfio)->segbits += (PTDtemp);           \
01087                         (xfio)->_cnt += (PTDtemp);              \
01088                         }
01089 
01090 /*
01091  * Get a small number of bits where it is not justified to call MOVBIT
01092  * The resultant bits are left justified in the word.
01093  * No checking is done. POINTERS AND COUNTS ARE NOT INCREMENTED
01094  * nbits MUST be <= 64.  When sizeof(long) == 64, 64 bits are always 
01095  * returned. When sizeof(long) == 32, 32 bits are always returned.
01096  */
01097 #if     defined(__mips) || defined(_LITTLE_ENDIAN)
01098 #define GET_BITS(outword,bufptr,nbits)                          \
01099                 {                                               \
01100                 register int qzshft;                            \
01101                 qzshft = BPBITOFF(bufptr);                      \
01102                 SANITYCHK((nbits),GT,64);                       \
01103                 SANITYCHK((nbits),LT,1);                        \
01104                 if (((qzshft & 07)== 0) && (((nbits) & 07) == 0)) \
01105                         {                                       \
01106                         char *_op;                              \
01107                         char *_bp;                              \
01108                         int   _iz;                              \
01109                         _bp = BPTR2CP(bufptr);                  \
01110                         _op = (char *)&(outword);               \
01111                         (outword) = 0;                          \
01112                         for (_iz = 0; _iz < (nbits)/8; _iz++)   \
01113                                 {                               \
01114                                 *_op++ = *_bp++;                \
01115                                 }                               \
01116                         }                                       \
01117                 else                                            \
01118                         {                                       \
01119                         (outword) = _dshiftl(*BPTR2WP(bufptr),  \
01120                                         *(BPTR2WP(bufptr)+1),   \
01121                                         qzshft)                 \
01122                         & _mask(nbits); /* mask from left */    \
01123                         }                                       \
01124                 }
01125 #else
01126 #define GET_BITS(outword,bufptr,nbits)                          \
01127                 {                                               \
01128                 register int qzshft;                            \
01129                 qzshft = BPBITOFF(bufptr);                      \
01130                 SANITYCHK((nbits),GT,64);                       \
01131                 SANITYCHK((nbits),LT,1);                        \
01132                 (outword) = _dshiftl(*BPTR2WP(bufptr),          \
01133                                         *(BPTR2WP(bufptr)+1),   \
01134                                         qzshft)                 \
01135                         & _mask(nbits); /* mask from left */    \
01136                 }
01137 #endif
01138 
01139 #if     defined(__mips) || defined(_LITTLE_ENDIAN)
01140 #define PUT_BITS(bufptr,idata,nbits)                                    \
01141                 {                                                       \
01142                 long P_Btmp1, P_Btmp2, *P_Bp;                           \
01143                 int P_Boff;                                             \
01144                 P_Boff = BPBITOFF(bufptr);                              \
01145                 if (((P_Boff & 07) == 0) && (((nbits)&07) == 0))        \
01146                         {                                               \
01147                         char *P_Bz;                                     \
01148                         int __i;                                        \
01149                         P_Bz =  BPTR2CP(bufptr);                        \
01150                         for (__i = 0; __i < (nbits)/8; __i++)           \
01151                                 *P_Bz++ = ((unsigned long)(idata) >> ((sizeof(long) -(__i+1))*8)) & 0xff; \
01152                         }                                               \
01153                 else                                                    \
01154                         {                                               \
01155                         P_Bp = BPTR2WP(bufptr);                         \
01156                         if ((P_Boff+(nbits)) <= _BITS_PER_LONG)         \
01157                                 {                                       \
01158                                 P_Btmp1 = 0;                            \
01159                                 P_Btmp2 = 0;                            \
01160                                 if (P_Boff != 0)                        \
01161                                         P_Btmp1 = (unsigned long)*P_Bp >> \
01162                                          (_BITS_PER_LONG - P_Boff);     \
01163                                 if ((P_Boff + (nbits)) != _BITS_PER_LONG) \
01164                                         P_Btmp2 = *P_Bp << (P_Boff + (nbits)); \
01165                                 P_Btmp1 = _dshiftl(P_Btmp1, idata, (nbits)); \
01166                                 *P_Bp = _dshiftl(P_Btmp1, P_Btmp2,      \
01167                                         _BITS_PER_LONG - (P_Boff + (nbits))); \
01168                                 }                                               \
01169                         else                                                    \
01170                                 {                                               \
01171                                 P_Btmp1 = (unsigned long)*P_Bp >>               \
01172                                  (_BITS_PER_LONG - P_Boff);                      \
01173                                 P_Btmp2 = *(P_Bp + 1) << (P_Boff+(nbits)-_BITS_PER_LONG);\
01174                                 *P_Bp = _dshiftl(P_Btmp1, (idata), _BITS_PER_LONG-P_Boff);\
01175                                 P_Btmp1 = _dshiftl(P_Btmp1, (idata), (nbits));  \
01176                                 *(P_Bp+1) = _dshiftr(P_Btmp1, P_Btmp2,          \
01177                                         P_Boff + (nbits) - _BITS_PER_LONG);\
01178                                 }                                               \
01179                         }                                                       \
01180                 }
01181 
01182 #else
01183 /*
01184  * PUT_BITS
01185  * Put a small number of bits (idata) in a specified place. (bufptr)
01186  * input data is left justified in the word.
01187  * This works only if the number of bits is less than 64.
01188  * No checking is done. POINTERS AND COUNTS ARE NOT INCREMENTED
01189  * This means that it works to put a few bits in place where there
01190  * is surrounding data (backpatching)
01191  * For 64-bit architectures, we assume idata is a 64-bit word.
01192  * For 32-bit architectures, we assume idata is a 32-bit word.
01193  */
01194 #define PUT_BITS(bufptr,idata,nbits)                                    \
01195                 {                                                       \
01196                 long P_Btmp1, P_Btmp2, *P_Bp;                           \
01197                 int P_Boff;                                             \
01198                 P_Boff = BPBITOFF(bufptr);                              \
01199                 P_Bp = BPTR2WP(bufptr);                                 \
01200                 if ((P_Boff+(nbits)) <= _BITS_PER_LONG)                 \
01201                         {                                               \
01202                         P_Btmp1 = 0;                                    \
01203                         P_Btmp2 = 0;                                    \
01204                         if (P_Boff != 0)                                \
01205                                 P_Btmp1 = (unsigned long)*P_Bp >>       \
01206                                  (_BITS_PER_LONG - P_Boff);             \
01207                         if ((P_Boff + (nbits)) != _BITS_PER_LONG)       \
01208                                 P_Btmp2 = *P_Bp << (P_Boff + (nbits));  \
01209                         P_Btmp1 = _dshiftl(P_Btmp1, idata, (nbits));    \
01210                         *P_Bp = _dshiftl(P_Btmp1, P_Btmp2,              \
01211                                 _BITS_PER_LONG - (P_Boff + (nbits)));   \
01212                         }                                               \
01213                 else                                                    \
01214                         {                                               \
01215                         P_Btmp1 = (unsigned long)*P_Bp >>               \
01216                          (_BITS_PER_LONG - P_Boff);                     \
01217                         P_Btmp2 = *(P_Bp + 1) << (P_Boff+(nbits)-_BITS_PER_LONG);\
01218                         *P_Bp = _dshiftl(P_Btmp1, (idata), _BITS_PER_LONG-P_Boff);\
01219                         P_Btmp1 = _dshiftl(P_Btmp1, (idata), (nbits));  \
01220                         *(P_Bp+1) = _dshiftr(P_Btmp1, P_Btmp2,          \
01221                                         P_Boff + (nbits) - _BITS_PER_LONG);\
01222                         }                                               \
01223                 }
01224 #endif
01225 
01226 /*
01227  * MOV_BITS
01228  *      Move the specified bits from a_a to b_b.
01229  */
01230 #if     defined(__mips) || defined(_SOLARIS) || defined(_LITTLE_ENDIAN)
01231 #define MOVBIT movbit_
01232 #define MOVBITZ movbitz_
01233 #endif
01234 
01235 #ifdef  _ABSOFT
01236 #define MOVBIT movbit
01237 #define MOVBITZ movbitz
01238 #endif
01239 
01240 extern void _memwcpy(long *_s, long *_s0, int _n);
01241 
01242 #if     defined(__mips)
01243 #define _MOVEM(to_b, frm_a, nbits)                                      \
01244                         {                                               \
01245                         long long       M_aoff, M_boff;                 \
01246                         M_aoff = BPBITOFF(frm_a);                       \
01247                         M_boff = BPBITOFF(to_b);                        \
01248                         if (((M_aoff & 07) | (M_boff & 07) |            \
01249                                         (nbits & 07)) == 0 )            \
01250                                 {                                       \
01251                                 memcpy(BPTR2CP(to_b), BPTR2CP(frm_a), \
01252                                 (nbits) / 8);                           \
01253                                 }                                       \
01254                         else                                            \
01255                                 {                                       \
01256                                 long long       M_Bits;                 \
01257                                                                         \
01258                                 M_Bits = (nbits);                       \
01259                                 M_aoff = BPBITOFF(frm_a);               \
01260                                 M_boff = BPBITOFF(to_b);                \
01261                                 SANITYCHK(M_aoff,GT,_BITS_PER_LONG)     \
01262                                 SANITYCHK(M_aoff,GT,_BITS_PER_LONG)     \
01263                                 MOVBITZ(BPTR2WP(frm_a), &M_aoff,        \
01264                                         &M_Bits, BPTR2WP(to_b), &M_boff);\
01265                                 }                                       \
01266                         }
01267 #elif   defined(_LITTLE_ENDIAN)
01268 #define _MOVEM(to_b, frm_a, nbits)                                      \
01269                         {                                               \
01270                         int64           M_aoff, M_boff;                 \
01271                         M_aoff = BPBITOFF(frm_a);                       \
01272                         M_boff = BPBITOFF(to_b);                        \
01273                         if (((M_aoff & 07) | (M_boff & 07) |            \
01274                                         (nbits & 07)) == 0 )            \
01275                                 {                                       \
01276                                 memcpy(BPTR2CP(to_b), BPTR2CP(frm_a), \
01277                                 (nbits) / 8);                           \
01278                                 }                                       \
01279                         else                                            \
01280                                 {                                       \
01281                                 int64           M_Bits;                 \
01282                                                                         \
01283                                 M_Bits = (nbits);                       \
01284                                 M_aoff = BPBITOFF(frm_a);               \
01285                                 M_boff = BPBITOFF(to_b);                \
01286                                 SANITYCHK(M_aoff,GT,_BITS_PER_LONG)     \
01287                                 SANITYCHK(M_aoff,GT,_BITS_PER_LONG)     \
01288                                 MOVBITZ(BPTR2WP(frm_a), &M_aoff,        \
01289                                         &M_Bits, BPTR2WP(to_b), &M_boff);\
01290                                 }                                       \
01291                         }
01292 #else
01293 #define _MOVEM(to_b, frm_a, nbits)                                      \
01294                         {                                               \
01295                         if ((BPBITOFF(frm_a) | BPBITOFF(to_b) |         \
01296                                         (nbits & 077)) == 0 )           \
01297                                 {                                       \
01298                                 _memwcpy(BPTR2WP(to_b), BPTR2WP(frm_a), \
01299                                 (nbits) / _BITS_PER_LONG);              \
01300                                 }                                       \
01301                         else                                            \
01302                                 {                                       \
01303                                 long    M_aoff, M_boff, M_Bits;         \
01304                                                                         \
01305                                 M_Bits = (nbits);                       \
01306                                 M_aoff = BPBITOFF(frm_a);               \
01307                                 M_boff = BPBITOFF(to_b);                \
01308                                 SANITYCHK(M_aoff,GT,_BITS_PER_LONG)     \
01309                                 SANITYCHK(M_aoff,GT,_BITS_PER_LONG)     \
01310                                 MOVBITZ(BPTR2WP(frm_a), &M_aoff,        \
01311                                         &M_Bits, BPTR2WP(to_b), &M_boff);\
01312                                 }                                       \
01313                         }
01314 #endif
01315 
01316 #define MOV_BITS(to_b,frm_a,bits)                                       \
01317                         {                                               \
01318                         SANITYCHK(BPTR2WP(frm_a),LE,(long *)100)        \
01319                         SANITYCHK(BPTR2WP(to_b),LE,(long *)100)         \
01320                         _MOVEM(to_b, frm_a, bits);                      \
01321                         }
01322 
01323 /*
01324  * Clear the status word.  These macros clear the iosw and ffsw structures.
01325  * Note that only the first three words of the ffsw are cleared.  This is
01326  * because the fourth word is new in UNICOS 7.0, and for safety is not used.
01327  * On machines where _ADDR64 is true (and MIPS), more space is cleared.
01328  */
01329 
01330 #if     defined(__mips) || defined(_LITTLE_ENDIAN)
01331 #define CLRSTAT(io_sw)          {*(int *)&(io_sw) = 0; io_sw.sw_count=0;}
01332 #else
01333 #define CLRSTAT(io_sw)          *(long *)&(io_sw) = 0
01334 #endif
01335 
01336 #if     defined(__mips) || defined(_LITTLE_ENDIAN)
01337 /* Clear through sw_sptr */
01338 #define CLRFFSTAT(io_sw)                                                \
01339                         {                                               \
01340                         long    *_ptr;                                  \
01341                         _ptr    = (long *)&(io_sw);                     \
01342                         *_ptr++ = 0;                                    \
01343                         *_ptr++ = 0;                                    \
01344                         *_ptr++ = 0;                                    \
01345                         *_ptr++ = 0;                                    \
01346                         *_ptr++ = 0;                                    \
01347                         *_ptr++ = 0;                                    \
01348                         }
01349 #elif   defined(_ADDR64) 
01350 #define CLRFFSTAT(io_sw)                                                \
01351                         {                                               \
01352                         long    *_ptr;                                  \
01353                         _ptr    = (long *)&(io_sw);                     \
01354                         *_ptr++ = 0;                                    \
01355                         *_ptr++ = 0;                                    \
01356                         *_ptr++ = 0;                                    \
01357                         *_ptr++ = 0;                                    \
01358                         }
01359 #else
01360 #define CLRFFSTAT(io_sw)                                                \
01361                         {                                               \
01362                         long    *_ptr;                                  \
01363                         _ptr    = (long *)&(io_sw);                     \
01364                         *_ptr++ = 0;                                    \
01365                         *_ptr++ = 0;                                    \
01366                         *_ptr++ = 0;                                    \
01367                         }
01368 #endif
01369 
01370 #if     defined(DEBUG) && !defined(__mips) && !defined(_LITTLE_ENDIAN)
01371 #define _STATPRINT(trcvar, nstat)                                       \
01372                         {                                               \
01373                         if (FDCTRACE(TRACE_STATUS))                     \
01374                                 {                                       \
01375                                 char _str[128];                         \
01376                                                                         \
01377                                 sprintf(_str,                           \
01378                                         "SETSTAT: %d, at line number %d in file %s\n", \
01379                                                 nstat, __LINE__, __FILE__); \
01380                                 _xrt_putstr(_str);                      \
01381                                 }                                       \
01382                         }
01383 
01384 #define _ERRPRINT(trcvar, errnum)                                       \
01385                         {                                               \
01386                         if (FDCTRACE(TRACE_STATUS))                     \
01387                                 {                                       \
01388                                 char _str[128];                         \
01389                                                                         \
01390                                 sprintf(_str,                           \
01391                                         "SETERROR: %d, at line number %d in file %s\n", \
01392                                                 errnum, __LINE__, __FILE__); \
01393                                 _xrt_putstr(_str);                      \
01394                                 }                                       \
01395                         }
01396 #else
01397 #define _STATPRINT(trcvar, nstat)
01398 #define _ERRPRINT(trcvar, errnum)
01399 #endif
01400 
01401 /*
01402  * Set the status field in the status struct.
01403  */
01404 #define _SETSTAT(io_sw,nstat,nbytes)    {                               \
01405                                 (io_sw)->sw_flag = 1;                   \
01406                                 (io_sw)->sw_error = 0;                  \
01407                                 (io_sw)->sw_count = (nbytes);           \
01408                                 (io_sw)->sw_stat = (nstat);             \
01409                                 }
01410 
01411 /*
01412  * Set the error status.  Always print the error in DEBUG mode
01413  */
01414 #define _SETERROR(io_sw,errnum,nbytes)  {                               \
01415                                 (io_sw)->sw_flag = 1;                   \
01416                                 (io_sw)->sw_error = (errnum);           \
01417                                 (io_sw)->sw_count = (nbytes);           \
01418                                 FFSTAT(*io_sw) = FFERR;                 \
01419                                 _ERRPRINT(TRACE_STATUS,errnum);         \
01420                                 }
01421 
01422 #define SETSTAT(io_sw,nstat,nbytes)     {                               \
01423                                 _SETSTAT(io_sw,nstat,nbytes);           \
01424                                 _STATPRINT(__fdctrace_enable,nstat);    \
01425                                 }
01426 
01427 /*
01428  * Set the status and return an error.  Always print the status in DEBUG mode
01429  */
01430 #define ERETURN(io_sw,errnum,nbytes)    {                               \
01431                                         _SETERROR(io_sw,errnum,nbytes); \
01432                                         return(ERR);                    \
01433                                         }
01434 
01435 #if     !defined(__mips) && !defined(_LITTLE_ENDIAN)
01436 #define _FFOPEN_ERETURN(_a,_b,_c) ERETURN((_a),(_b),(_c))
01437 #define _FFOPEN_ERR ERR
01438 #else
01439 #define _FFOPEN_ERR (_ffopen_t) -1L
01440 #define _FFOPEN_ERETURN(_a,_b,_c) { \
01441         _SETERROR((_a),(_b),(_c)); \
01442         return(_FFOPEN_ERR); }
01443 #endif
01444 
01445 /*
01446  * These are the 'generic' SCC codes.  They are the ones that
01447  * are used internally and translated into those for IBM and VMS
01448  * Having the FULL code =0 has the advantage if no SCCs need to be
01449  * processed.
01450  */
01451 #define SCCUNKN -1      /* This does not translate into a 'real' SCC code */
01452 #define SCCFULL 0
01453 #define SCCFRST 1
01454 #define SCCLAST 2
01455 #define SCCMIDL 3
01456 
01457 /*
01458  * segment control code definitions fr all classes
01459  */
01460 #define SCC_IBM         0       /* IBM type Segment Control code */
01461 #define SCC_VMS         1       /* VMS type Segment Control code */
01462 #define SCC_CDC         2       /* CDC type Segment Control code */
01463 #define SCC_NVE         3       /* CDC type Segment Control code */
01464 
01465 /*
01466  * Number of SCC types.  This is for the scc table dimension
01467  */
01468 #define NUM_SCC_TYPES   4       /* IBM, VMS and CDC, and NOS/VE*/
01469 
01470 /*
01471  * error codes for FDC parameters while parsing the -F assign attribute.
01472  */
01473 #define FDC_PERR_CLASS  1
01474 #define FDC_PERR_RFC    2
01475 #define FDC_PERR_RFCS   3
01476 #define FDC_PERR_RSZ    4
01477 #define FDC_PERR_MBS    5
01478 #define FDC_PERR_MIN    6
01479 #define FDC_PERR_MAX    7
01480 #define FDC_PERR_INC    8
01481 #define FDC_PERR_BAD    9
01482 
01483 #define NUM_PERRS       9
01484 
01485 /*
01486  * fddcvrt_u: foreign dataset data conversion descriptor word.
01487  *      This word contains fields that describe the users
01488  *      request for data conversion.
01489  *
01490  *
01491  *  0                                                              64
01492  * /--------+--------+--------+----------------------------------------\
01493  * |vers    | bin    | char   |                                        |
01494  * |info    | cvrt   | set    |          unused     ...(40 bits)       |
01495  * | 8 bits | 8 bits | 8 bits |                                        |
01496  * \--------+--------+--------+----------------------------------------/
01497  *  ^        ^        ^
01498  *  zero     ^        ^
01499  *  for      ^        ^
01500  *  now      ^        ^
01501  *           ^        ^
01502  *           ^        ^
01503  *           ^        ^
01504  *           ^        ^
01505  *           ^        ^
01506  *           ^        1=ascii
01507  *           ^        2=ebcdic
01508  *           ^        etc...
01509  *           ^
01510  *           2=binary - IBM
01511  *           3=binary - CDC
01512  *           etc..
01513  */
01514 union fddcvrt_u
01515         {
01516         struct
01517                 {
01518                 int     vers:8;         /* version ID, zero for now */
01519                 int     cvrt:8;         /* numeric conversion code */
01520                 int     cvch:8;         /* character conversion code */
01521                 int     cvch_opt:8;     /* text record options */
01522                 int     unused:32;
01523                 } fld;
01524         unsigned long   wword;
01525         };
01526 
01527 /*
01528  * spec_u:
01529  *
01530  *      FFIO specification word.  A sequence of one or more of consecutive
01531  *      spec_u words is used to pass FFIO layer parameters to any layer's
01532  *      open routine.
01533  *
01534  *      The first 8 bits of each spec_u word contain the extension bit and the
01535  *      class.  The extension bit is set in all but the last spec_u word
01536  *      in a spec_u word sequence.
01537  *
01538  *      The remainder of each word can contain different info depending on
01539  *      class.
01540  *
01541  *      Before changing spec_u, be sure the new structure will maintain
01542  *      compatibility between new versions of the asgcmd command and old
01543  *      libraries.
01544  *
01545  *      Starting in UNICOS 7.0, a "standard default sequence" of spec_u words
01546  *      is used for most layers.  The sequence generated by layer specification
01547  *
01548  *                      layer.str1.str2:num1:num2:num3:...:numN
01549  *
01550  *      is:
01551  *
01552  * Word 0 (hdr):
01553  * -------------
01554  *  0                                                                   64
01555  * /-+-+-----+--------+----+----+--------------------+--------------------\
01556  * |e| |class| str1   |str2|          unused                              |
01557  * |x| |     |        |    |                                              |
01558  * |t| |6-bit| 8-bits |4bit|          44-bits                             |
01559  * \-+-+-----+--------+----+----+--------------------+--------------------/
01560  *
01561  * Words 1..N (info):
01562  * ------------------
01563  *  0                                                                   64
01564  * /-+-+-----+--------+----+----+--------------------+--------------------\
01565  * |e|v|class|                        value                               |
01566  * |x|a|     |                                                            |
01567  * |t|l|6-bit|                        56-bits                             |
01568  * \-+-+-----+--------+----+----+--------------------+--------------------/
01569  *
01570  *
01571  * Spec_u word format used for SDS and MR layers:
01572  *
01573  * Word 0 (fss):
01574  * -------------
01575  *  0                                                                   64
01576  * /-+-+-----+--------+----+----+--------------------+--------------------\
01577  * |e| |class| recfmt |styp|    |                min                      |
01578  * |x| |     |        |    |    |                                         |
01579  * |t| |6-bit| 8-bits |4bit|    |              40-bits                    |
01580  * \-+-+-----+--------+----+----+--------------------+--------------------/
01581  *
01582  *
01583  * Spec_u word 0 format used for compatibility between asgcmd and old libraries:
01584  *
01585  * Word 0 (fld):
01586  * -------------
01587  *  0                                                                   64
01588  * /-+-+-----+--------+----+----+--------------------+--------------------\
01589  * |e| |class| recfmt |styp|    |     recsize        |     mbs            |
01590  * |x| |     |        |    |    |                    |                    |
01591  * |t| |6-bit| 8-bits |4bit|    |     20-bits        |     20-bits        |
01592  * \-+-+-----+--------+----+----+--------------------+--------------------/
01593  *
01594  * Spec_u word 0 format used by new assign parser
01595  *
01596  * Word 0 (fld):
01597  * -------------
01598  *  0                                                                   64
01599  * /-+-+-----+--------+----+----+--------------------+--------------------\
01600  * |e| |class| info        |     recsize        |     mbs            |
01601  * |x| |     |             |    |                    |                    |
01602  * |t| |6-bit| 12-bits     |    |     20-bits        |     20-bits        |
01603  * \-+-+-----+--------+----+----+--------------------+--------------------/
01604  */
01605 #if     defined(_CRAY) || defined(__mips) || defined(_LITTLE_ENDIAN)
01606 /*
01607    #ifndef      uint64
01608    #define uint64 unsigned long long
01609    #endif
01610    #ifndef      int64
01611    #define int64 long long
01612    #endif
01613 */
01614 typedef uint64 _spect;  /* 64-bit unsigned integer */
01615 #else
01616 typedef unsigned _spect;
01617 #endif
01618 union spec_u
01619         {
01620         struct
01621                 {
01622                 _spect ext      :1;     /* ext bit is on if not end of spec */
01623                 _spect          :1;
01624 #ifndef __cplusplus
01625                 _spect class    :6;     /* ffio CLASS */
01626 #else
01627                 _spect classsp  :6;     /* ffio CLASS */
01628 #endif
01629                 _spect str1     :8;     /* string parameter 1 */
01630                 _spect str2     :4;     /* string parameter 2 */
01631                 } hdr;
01632         struct
01633                 {
01634                 _spect ext      :1;     /* set to 1 if not end of spec */
01635                 _spect valid    :1;     /* set to 1 if this param was passed */
01636 #ifndef __cplusplus
01637                 _spect class    :6;     /* ffio CLASS */
01638 #else
01639                 _spect classsp :6;      /* ffio CLASS */
01640 #endif
01641 #if     defined(_WORD32) && !defined(__mips) && !defined(_LITTLE_ENDIAN)
01642                 unsigned quan;          /* numeric parameter value */
01643 #else
01644                 _spect quan     :56;    /* numeric parameter value */
01645 #endif
01646                 } info;
01647         struct
01648                 {
01649                 _spect ext      :1;     /* ext bit is on if not end of spec */
01650                 _spect          :1;
01651 #ifndef __cplusplus
01652                 _spect class    :6;     /* ffio CLASS */
01653 #else
01654                 _spect classsp  :6;     /* ffio CLASS */
01655 #endif
01656                 _spect recfmt   :8;     /* This is the record format */
01657                 _spect subtype  :4;     /* record format subtype. */
01658 #if     defined(_WORD32)  && !defined(__mips) && !defined(_LITTLE_ENDIAN)
01659                 unsigned min;
01660 #else
01661                 _spect          :4;
01662                 _spect min      :40;
01663 #endif
01664                 } fss;
01665         struct
01666                 {
01667                 _spect ext      :1;     /* ext bit is on if not end of spec */
01668                 _spect unused1  :1;
01669 #ifndef __cplusplus
01670                 _spect class    :6;     /* ffio CLASS */
01671 #else
01672                 _spect cpasssp  :6;     /* ffio CLASS */
01673 #endif
01674                 _spect recfmt   :8;     /* This is the record format */
01675                 _spect subtype  :4;     /* record format subtype. */
01676                 _spect          :4;
01677                 _spect recsize  :20;
01678                 _spect mbs      :20;
01679                 } fld;
01680         struct
01681                 {
01682                 _spect ext      :1;     /* ext bit is on if not end of spec */
01683                 _spect unused1  :1;
01684 #ifndef __cplusplus
01685                 _spect class    :6;     /* ffio CLASS */
01686 #else
01687                 _spect cpasssp  :6;     /* ffio CLASS */
01688 #endif
01689                 _spect info1    :24;    /* This contains non-numeric info */
01690                 _spect info2    :32;    /* This contains more non-numeric info */
01691                 } class_info;
01692 #if     defined(_CRAY) || defined(__mips) || defined(_LITTLE_ENDIAN)
01693         _spect wword;   
01694 #elif   defined(_WORD32)
01695         unsigned long long wword;
01696 #else
01697 #error "THIS CASE IS NOT HANDLED"
01698 #endif
01699         };
01700 
01701 /*
01702  * Find the next start of spec..
01703  *      Skip the extension words.
01704  */
01705 #define NEXT_SPEC(nxtspec)      { nxtspec = _next_spec(nxtspec); }
01706 #include <cray/mtlock.h>
01707 
01708 /*
01709  *      Global open information packet.  This structure contains information
01710  *      intended to be shared by all FFIO layers in a chain.
01711  */
01712 struct gl_o_inf {
01713         int             version;        /* version number for gl_o_inf  */
01714                                         /* structure.  Is 0 in 8.1+ libraries */
01715         enum {
01716           OT_FORTRAN=1,
01717           OT_USER1=2,
01718           OT_USER2=4,
01719           OT_USER3=8,
01720           OT_USER4=16,
01721           OT_USER5=32,
01722           OT_USER6=64,
01723           OT_USER7=128,
01724           OT_USER8=256,
01725           OT_USER9=512,
01726           OT_SSIO=1024
01727         }               open_type;      /* code for type of open        */
01728 
01729         union {
01730          struct {                       /* for Fortran files ...        */
01731           unum_t        unum;           /* unit number (-1 if unknown)  */
01732           unsigned      is_seq:1;       /* 1 iff access='sequential'    */
01733           unsigned      is_fmt:1;       /* 1 iff form='formatted'       */
01734           long          reclen;         /* 0 or RECL= value             */
01735          } fort;        
01736          int            pad_a[15];      /* pad for future expansion     */
01737         } u;
01738 
01739         unsigned        alreadyopen:1;  /* 1 iff file is already opened and */
01740                                         /* "fd" contains file descriptor.   */
01741                                         /* Used only by _gsys_open and      */
01742                                         /* _bmx_open.                       */
01743 
01744 
01745         int             fd;             /* file descriptor of already-open  */
01746                                         /* tape file.                       */
01747 
01748         int             depth;          /* FFIO layer depth (1 == top level)*/
01749 
01750         struct assign_info_s
01751                         *aip;           /* assign info, or NULL */
01752 
01753         int             pad_b[4];       /* pad for future expansion */
01754 
01755         int64           user[2];        /* reserved for user layers */
01756         int64           site[2];        /* reserved for site layers */
01757 
01758 };
01759 
01760 /*
01761  * This structure defines the function pointers that comprise the standard
01762  * interface that is used between layers of the FDC process.
01763  */
01764 #if     defined(__mips) || defined(_LITTLE_ENDIAN)
01765 typedef struct fdinfo * _ffopen_t;
01766 typedef off_t           _ffseek_t;
01767 #else
01768 typedef int             _ffopen_t;
01769 typedef int             _ffseek_t;
01770 #endif
01771 
01772 #if     defined(__mips) || defined(_LITTLE_ENDIAN)
01773 #define ___(A) A
01774 #else
01775 #define ___(A) ()
01776 #endif
01777 
01778 struct xtr_s
01779         {
01780 
01781         /* Specific open processing for the file type */
01782         _ffopen_t (* openrtn) ___((const char *_Name, int _Flags, mode_t _Mode, struct fdinfo *_Fio, union spec_u *_Spec, struct ffsw *_Retstat, long _Cbits, int _Cblks, struct gl_o_inf *_Oinf));
01783 
01784         /* Read one block/record of data packed */
01785         ssize_t (* readrtn) ___((struct fdinfo *_Fio, bitptr _Bufptr, size_t _Nbytes, struct ffsw *_Retstat, int _Fulp, int *_Ubc));
01786 
01787         /* Read one block/record of data async */
01788         ssize_t (* readartn) ___((struct fdinfo *_Fio, bitptr _Bufptr, size_t _Nbytes, struct ffsw *_Retstat, int _Fulp, int *_Ubc));
01789 
01790         /* Read one block/record of data 1 char/wd */
01791         ssize_t (* readcrtn) ___((struct fdinfo *fio, bitptr _Bufptr, size_t _Nbytes, struct ffsw *_Restat, int _Fulp));
01792 
01793         /* Write one block/record of data packed */
01794         ssize_t (* writertn) ___((struct fdinfo *_Fio, bitptr _Bufptr, size_t _Nbytes, struct ffsw *_Retstat, int _Fulp, int *_Ubc));
01795 
01796         /* Write one block/record of data async */
01797         ssize_t (* writeartn) ___((struct fdinfo *_Fio, bitptr _Bufptr, size_t _Nbytes, struct ffsw *_Retstat, int _Fulp, int *_Ubc));
01798 
01799         /* Write one block/record of data 1 char/wd */
01800         ssize_t (* writecrtn) ___((struct fdinfo *_Fio, bitptr _Bufptr, size_t _Nbytes, struct ffsw *_Restat, int _Fulp));
01801 
01802         /* Do any special cleanup and close file */
01803         int (* closertn) ___((struct fdinfo *_Fio, struct ffsw *_Retstat));
01804 
01805         /* Flush the buffers */
01806         int (* flushrtn) ___((struct fdinfo *_Fio, struct ffsw *_Retstat));
01807 
01808         /* endfile routine, not always meaningful */
01809         int (* weofrtn) ___((struct fdinfo *_Fio, struct ffsw *_Retstat));
01810 
01811         /* end of data routine "the REAL end" */
01812         int (* weodrtn) ___((struct fdinfo *_Fio, struct ffsw *_Retstat));
01813 
01814         /* seek on foreign file?? */
01815         _ffseek_t (* seekrtn) ___((struct fdinfo *_Fio, off_t _Pos, int whence, struct ffsw *_Retstat));
01816 
01817         /* backspace routine */
01818         int (* backrtn) ___((struct fdinfo *_Fio, struct ffsw *_Retstat));
01819 
01820         /* positioning routine */
01821         _ffseek_t (* posrtn) ___((struct fdinfo *_Fio, int _Cmd, void *_Arg, int _Len, struct ffsw *_Stat));
01822 
01823         /* listio routine */
01824         int (* listiortn) ___((int _Cmd, struct fflistreq *_List, int _Nent, struct ffsw *_Stat)); 
01825 
01826         int (* fcntlrtn) ___((struct fdinfo *_Fio, int _Cmd, void *_Arg, struct ffsw *_Stat));  /* fcntl routine */
01827         };
01828 
01829 /* 
01830  * Remove definition of ___
01831  */
01832 #undef  ___
01833 
01834 /*
01835  * the fdinfo block is a sort of 'DSP' for FDC.  It contains all of the
01836  * state information used by the various routines.
01837  */
01838 struct fdinfo
01839         {
01840         long    magic;          /* magic number for ID */
01841         int     realfd;         /* Our real file descriptor number */
01842                                 /* this is only used by layers that have */
01843                                 /* either private implementations, or */
01844                                 /* 'real' file descriptors. */
01845         struct fdinfo *fioptr;  /* Pointer to fdinfo block for next */
01846                                 /* lower level. */
01847         struct fdinfo *parptr;  /* Pointer to fdinfo block for parent layer */
01848 
01849         struct stat *lstp;      /* Pointer to result of last stat/ffstat call */
01850                                 /* If null, none has been done */
01851         long    opn_flags;      /* Flags used in open call */
01852 /*
01853  *      info about blocks and records
01854  */
01855         int     subtype;        /* record subtype (block type for CDC) */
01856         int64   maxrecsize;     /* max record size in BITS */
01857         int64   maxblksize;     /* Maximum Block Size (MBS) in BITS */
01858 #ifndef __cplusplus
01859         int     class;          /* record translation class */
01860 #else
01861         int     classfdinfo;    /* record translation class */
01862 #endif
01863         int     rtype;          /* Record type, as defined above */
01864 /*
01865  *      Counters.  These are the counts of data and such in the buffer(s).
01866  *      Note:  All counts are kept and passed in bits.
01867  */
01868         int64   recbits;        /* total number of bits in logical record */
01869                                 /* This is only valid after a partial read */
01870                                 /* or write.  It is reset at each EOR/EOF */
01871         long    segbits;        /* number of bits left in segment */
01872                                 /* This always indicates the amount */
01873                                 /* of 'clear' data to be processed. */
01874                                 /* on write, this is the number of bits */
01875                                 /* already in the buffer, on read, the */
01876                                 /* number left in the buffer */
01877         int     scc;            /* segment control code */
01878         int     lastscc;        /* segment control code for prev. segment. */
01879         int64   last_recbits;   /* record length of last record in BITS */
01880                                 /* This is used differently in various layers */
01881 /*
01882  *      Buffer info
01883  */
01884         bitptr  _base;          /* BIT pointer */
01885         bitptr  _ptr;           /* BIT pointer to next data in buffer */
01886         long    _cnt;           /* BIT count. Bits left in buffer on read*/
01887                                 /*            Bits accumulated on write */
01888         long    _ffbufsiz;      /* BIT size of buffer */
01889 
01890 /*
01891  *      Flags
01892  */
01893         int rwflag;             /* 4 for position, 2 for write, 1 for read */
01894                                 /* This tells what the last operation was, */
01895                                 /* nothing about open mode(s) */
01896         unsigned atbod:1;       /* _TRUE if at beginning of data */
01897         unsigned ateor:1;       /* _TRUE if at end of record */
01898         unsigned ateof:1;       /* _TRUE if EOF was last op (read or write) */
01899         unsigned ateod:1;       /* _TRUE if EOD was last op (read or write) */
01900         unsigned can_listio:1;  /* _TRUE if layer can handle listio */
01901         unsigned lock:1;        /* _TRUE if ffxxx routines need to lock */
01902         unsigned reg_lock:1;    /* _TRUE if ffxxx rtns use regular locks */
01903         unsigned free_lock:1;   /* _TRUE if a lock layer needs to free */
01904         plock_t *lock_word;     /* layers request that we use their lock */
01905         int     rsv6;           /* reserved for CRI */
01906 /*
01907  *      Function pointers (!)
01908  */
01909         struct xtr_s xr;        /* pointers to routines that do the work. */
01910 /*
01911  *      record type specific information
01912  */
01913         void    *lyr_info;      /* private layer info block ptr */
01914         };
01915 
01916 /* extern declarations */
01917 
01918 extern int __fdctrace_enable;   /* debugging flags */
01919 
01920 extern int _scc_tab[NUM_SCC_TYPES][4];
01921 
01922 /*
01923  *      These prototypes are for internal functions which a user may not
01924  *      use by default.
01925  */
01926 #if     defined(__mips) || defined(_CRAY) || defined(_LITTLE_ENDIAN)
01927 typedef int64 _nparmtype;       /* type of numeric parameters */
01928 #else
01929 typedef int _nparmtype;
01930 #endif
01931 extern _nparmtype _ff_nparm_getv (union spec_u *spec, int parnum, int *isvalid);
01932 extern int _ff_nparm_getcnt (union spec_u *spec);
01933 extern union spec_u *_next_spec(union spec_u *sp);
01934 
01935 extern _ffopen_t _ffopen (const char *name, int flags, mode_t mode,
01936         union spec_u *spek, struct ffsw *stat, long cbits, int cblks,
01937         struct fdinfo *pa_fio, struct gl_o_inf *oinf);
01938 
01939 extern int _ffopensg(const char *name, int flags, mode_t mode,
01940         long cbits, int cblks, struct ffsw *stat,
01941         const char *cspec, struct gl_o_inf *oinf);
01942 
01943 #if     defined(__mips) || defined(_LITTLE_ENDIAN)
01944 extern int _ff_fdinfo_to_int(_ffopen_t fd, struct ffsw *pstat);
01945 #else
01946 #define _ff_fdinfo_to_int(fd, pstat)    ((int)(fd))
01947 #endif
01948 
01949 #endif  /* _LIB_INTERNAL */
01950 
01951 #if     defined(__mips) || defined(_LITTLE_ENDIAN)
01952 __BEGIN_DECLS
01953 extern int ffassign (char *cmd);
01954 extern int ffbksp (int _Fd);
01955 extern int ffclose (int _Fd);
01956 extern ssize_t ffread (int _Fd, void *_Buf, size_t _Nb);
01957 extern ssize_t ffwrite (int _Fd, const void *_Buf, size_t _Nb );
01958 extern off_t ffseek (int _Fd, off_t _Pos, int _Whence );
01959 extern int ffweof (int _Fd);
01960 extern int ffweod (int _Fd);
01961 extern int ffopens (const char *_Name, int _Oflag, mode_t _Mode, long _Cbits,
01962         int _Cblks, struct ffsw *_Stat, const char *_Str);
01963 extern int fffcntl (int _Fd, int _Cmd, void *_Arg, struct ffsw *_Stat);
01964 extern off_t ffpos (int _Fd, int _Cmd, void *_Arg, int _Len,
01965         struct ffsw *_Stat);
01966 extern int ffflush (int _Fd, struct ffsw *_Stat);
01967 extern char *ffstrerror(int _Errnum);
01968 __END_DECLS
01969 #else
01970 #include <cray/clibinc_config.h>
01971 #if     !defined(_CRAYT3E) && _CRAYLIBS_RELEASE < 3000
01972 #define _USE_OLD_PROTOTYPE 1
01973 #endif
01974 __BEGIN_DECLS
01975 extern int ffbksp (int _Fd, ...);
01976 extern int ffclose (int _Fd, ...);
01977 extern int fffcntl (int _Fd, int _Cmd, ...);
01978 extern int ffflush (int _Fd, ...);
01979 extern int fflistio (int _Cmd, struct fflistreq *_List, int _Nent, ...);
01980 extern int ffopens (const char *_Name, int _Oflag, int _Mode, long _Cbits,
01981         ... );
01982 extern int ffpos (int _Fd, int _Cmd, long *_Arg, int _Len,
01983         struct ffsw *_Stat);
01984 extern char *ffstrerror(int _Errnum);
01985 #if     _USE_OLD_PROTOTYPE
01986 extern int ffread (int _Fd, char *_Buf, int _Nb, ...);
01987 #else
01988 extern int ffread (int _Fd, void *_Buf, size_t _Nb, ...);
01989 #endif
01990 extern int ffreada (int _Fd, char *_Buf, int _Nb, struct ffsw *_Stat, ...);
01991 extern int ffreadc (int _Fd, char *_Buf, int _Nb, ...);
01992 #if     _USE_OLD_PROTOTYPE
01993 extern int ffseek (int _Fd, int _Pos, int _Whence, ...);
01994 #else
01995 extern int ffseek (int _Fd, off_t _Pos, int _Whence, ...);
01996 #endif
01997 extern int ffsetsp (int _Fd, ...);
01998 extern int ffweod (int _Fd, ...);
01999 extern int ffweof (int _Fd, ...);
02000 #if     _USE_OLD_PROTOTYPE
02001 extern int ffwrite (int _Fd, char *_Buf, int _Nb, ...);
02002 #else
02003 extern int ffwrite (int _Fd, const void *_Buf, size_t _Nb, ...);
02004 #endif
02005 extern int ffwritea (int _Fd, char *_Buf, int _Nb, struct ffsw *_Stat, ...);
02006 extern int ffwritec (int _Fd, char *_Buf, int _Nb, ...);
02007 __END_DECLS
02008 #endif
02009 __BEGIN_DECLS
02010 extern int ffbkspf (int _Fd, struct ffsw *_Stat);
02011 extern int ffopen (const char *_Name, int _Oflag, ...);
02012 extern int ffopenf (const char *_Name, int _Oflag, mode_t _Mode, long _Cbits,
02013  int _Cblks, struct ffsw *_Pstat);
02014 extern int ffiolock (int _fd, struct ffsw *_Stat);
02015 extern int ffiounlock (int _fd, struct ffsw *_Stat);
02016 extern int ffclosef (int _Fd, struct ffsw *_Stat);
02017 extern int ffweoff (int _Fd, struct ffsw *_Stat);
02018 extern int ffweodf (int _Fd, struct ffsw *_Stat);
02019 extern off_t ffseekf (int _Fd, off_t _Pos, int _Whence, struct ffsw *_Stat);
02020 extern ssize_t ffreadf (int _Fd, void *_Buf, size_t _Nb, struct ffsw *_stat, int _Fulp, int *_Ubc);
02021 
02022 extern ssize_t ffwritef (int _Fd, const void *_Buf, size_t _Nb, struct ffsw *_stat, int _Fulp, int *_Ubc);
02023 __END_DECLS
02024 
02025 #endif /* !_FFIO_H */

Generated on Thu Dec 18 05:51:53 2008 for Open64 (mfef90, whirl2f, and IR tools) by  doxygen 1.5.7.1