1[Quoting from a C/370 manual, courtesy of Carl Forde.]
2
3  C/370 supports three types of input and output: text streams, binary
4  streams, and record I/O.  Text and binary streams are both ANSI
5  standards; record I/O is a C/370 extension.
6
7[...]
8
9  Record I/O is a C/370 extension to the ANSI standard.  For files
10  opened in record format, C/370 reads and writes one record at a
11  time.  If you try to write more data to a record than the record
12  can hold, the data is truncated.  For record I/O, C/370 only allows
13  the use of fread() and fwrite() to read and write to the files.  Any
14  other functions (such as fprintf(), fscanf(), getc(), and putc())
15  fail.  For record-orientated files, records do not change size when
16  you update them.  If the new data has fewer characters than the
17  original record, the new data fills the first n characters, where
18  n is the number of characters of the new data.  The record will
19  remain the same size, and the old characters (those after) n are
20  left unchanged.  A subsequent update begins at the next boundary.
21  For example, if you have the string "abcdefgh":
22
23  abcdefgh
24
25  and you overwrite it with the string "1234", the record will look
26  like this:
27
28  1234efgh
29
30  C/370 record I/O is binary.  That is, it does not interpret any of
31  the data in a record file and therefore does not recognize control
32  characters.
33
34
35  The record model consists of:
36
37  * A record, which is the unit of data transmitted to and from a
38    program
39  * A block, which is the unit of data transmitted to and from a
40    device.  Each block may contain one or more records.
41
42  In the record model of I/O, records and blocks have the following
43  attributes:
44
45  RECFM   Specifies the format of the data or how the data is organized
46          on the physical device.
47  LRECL   Specifies the length of logical records (as opposed to
48          physical ones).
49
50  BLKSIZE Specifies the length of physical records (blocks on the
51          physical device).
52
53
54  Opening a File by Filename
55
56  The filename that you specify on the call to fopen() or freopen()
57  must be in the following format:
58
59  >> ----filename---- ----filetype--------------------
60                   |   |             |             |
61                   --.--             -- --filemode--
62                                     |   |
63                                     --.--
64  where
65
66  filename is a 1- to 8-character string of any of the characters,
67  A-Z, a-z, 0-9, and +, -, $, #, @, :, and _.  You can separate it
68  from the filetype with one or more spaces, or with a period.
69  [Further note:  filenames are fully case-sensitive, as in Unix.]
70
71  filetype is a 1- to 8-character string of any of the characters,
72  A-Z, a-z, 0-9, and +, -, $, #, @, :, and _.  You can separate it
73  from the filemode with one or more spaces, or with a period. The
74  separator between filetype and filemode must be the same as the
75  one between filename and filetype.
76
77  filemode is a 1- to 2-character string.  The first must be any of
78  the characters A-Z, a-z, or *.  If you use the asis parameter on
79  the fopen() or freopen() call, the first character of the filemode
80  must be a capital letter or an asterisk.  Otherwise, the function
81  call fails.  The second character of filemode is optional; if you
82  specify it, it must be any of the digits 0-6.  You cannot specify
83  the second character if you have specified * for the first one.
84
85  If you do not use periods as separators, there is no limit to how
86  much whitespace you can have before and after the filename, the
87  filetype, and filemode.
88
89
90  Opening a File without a File Mode Specified
91
92  If you omit the file mode or specify * for it, C/370 does one
93  of the following when you call fopen() or freopen():
94
95  * If you have specified a read mode, C/370 looks for the named file
96    on all the accessed readable disks, in order.  If it does not find
97    the file, the fopen() or freopen() call fails.
98  * If you have specified any of the write modes, C/370 writes the file
99    on the first writable disk you have accessed.  Specifying a write
100    mode on an fopen() or freopen() call that contains the filename of
101    an existing file destroys that file.  If you do not have any
102    writable disks accessed, the call fails.
103
104
105  fopen() and freopen() parameters
106
107  recfm
108     CMS supports only two RECFMs, V and F.  [note that MVS supports
109     27(!) different RECFMs.]  If you do not specify the RECFM for a
110     file, C/370 determines whether is is in fixed or variable format.
111
112  lrecl and blksize
113     For files in fixed format, CMS allows records to be read and
114     written in blocks.  To have a fixed format CMS file treated as a
115     fixed blocked CMS file, you can open the file with recfm=fb and
116     specify the lrecl and blksize.  If you do not specify a recfm on
117     the open, the blksize can be a multiple of the lrecl, and the
118     file is treated as if it were blocked.
119
120     For files in variable format, the CMS LRECL is different from the
121     LRECL for the record model.  In the record model, the LRECL is
122     equal to the data length plus 4 bytes (for the record descriptor
123     word), and the BLKSIZE  is equal to the LRECL plus 4 bytes (for
124     the block descriptor word).  In CMS, BDWs and RDWs do not exist,
125     but because CMS follows the record model, you must still account
126     for them.  When you specify V, you must still allocate the record
127     descriptor word and block descriptor word.  That is, if you want
128     a maximum of n bytes per record, you must specify a minimum LRECL
129     of n+4 and a minimum BLKSIZE of n+8.
130
131     When you are appending to V files, you can enlarge the record size
132     dynamically, but only if you have not specified LRECL or BLKSIZE
133     on the fopen() or freopen() command that opened the file.
134
135  type
136     If you specify this parameter, the only valid value for CMS disk
137     files is type =record. This opens a file for record I/O.
138
139  asis
140     If you use this parameter, you can open files with mixed-case
141     filenames such as JaMeS dAtA or pErCy.FILE.  If you specify this
142     parameter, the file mode that you specify must be a capital letter
143     (if it is not an asterisk); otherwise; the function call fails and
144     the value returned is NULL.
145
146
147  Reading from Record I/O Files
148     fread() is the only interface allowed for reading record I/O files.
149     Each time you call fread() for a record I/O file, fread() reads
150     one record from the system.  If you call fread() with a request for
151     less than a complete record, the requested bytes are copied to your
152     buffer, and the file position is set to the start fo the next
153     record.  If the request is for more bytes that are in the record,
154     one record is read and the position is set to the start of the next
155     record.  C/370 does not strip any blank characters or interpret any
156     data.
157
158     fread() returns the number of items read successfully, so if you
159     pass a size argument equal to 1 and a count argument equal to the
160     maximum expected length of the record, fread() returns the length,
161     in bytes, of the record read.  If you pass a size argument equal
162     to the maximum expected length of the record, and a count argument
163     equal to 1, fread() returns either 0 or 1, indicating whether a
164     record of length size read.  If a record is read successfully but
165     is less than size bytes long, fread() returns 0.
166
167
168  Writing to Record I/O Files
169     fwrite() is the only interface allowed for writing to a file
170     opened for record I/O.  Only one record is written at a time.  If
171     you attempt to write more new data than a full record can hold or
172     try to update a record with more data than it currently has, C/370
173     truncates your output at the record boundary.  When C/370 performs
174     a truncation, it sets errno and raises SIGIOERR, if SIGIOERR is not
175     set to SIG_IGN.
176
177     When you are writing new records to a fixed-record I/O file, if you
178     try to write a short record, C/370 pads the record with nulls out
179     to LRECL.
180
181     At the completion of an fwrite(), the file position is at the start
182     of the next record.  For new data, the block is flushed out to the
183     system as soon as it is full.
184
185
186  fldata() Behavior
187     When you call the fldata() function for an open CMS minidisk file,
188     it returns a data structure that looks like this:
189
190     struct __filedata {
191          unsigned int   __recfmF      : 1, /* fixed length records */
192                         __recfmV      : 1, /* variable length records */
193                         __recfmU      : 1, /* n/a */
194                         __recfmS      : 1, /* n/a */
195                         __recfmBlk    : 1, /* n/a */
196                         __recfmASA    : 1, /* text mode and ASA */
197                         __recfmM      : 1, /* n/a */
198                         __dsorgPO     : 1, /* n/a */
199                         __dsorgPDSmem : 1, /* n/a */
200                         __dsorgPDSdir : 1, /* n/a */
201                         __dsorgPS     : 1, /* sequential data set */
202                         __dsorgConcat : 1, /* n/a */
203                         __dsorgMem    : 1, /* n/a */
204                         __dsorgHiper  : 1, /* n/a */
205                         __dsorgTemp   : 1, /* created with tmpfile() */
206                         __dsorgVSAM   : 1, /* n/a */
207                         __reserve1    : 1, /* n/a */
208                         __openmode    : 2, /* see below 1 */
209                         __modeflag    : 4, /* see below 2 */
210                         __reserve2    : 9, /* n/a */
211
212          char           __device;  __DISK
213          unsigned long  __blksize,         /* see below 3 */
214                         __maxreclen;       /* see below 4 */
215          unsigned short __vsamtype;        /* n/a */
216          unsigned long  __vsamkeylen;      /* n/a */
217          unsigned long  __vsamRKP;         /* n/a */
218          char *         __dsname;          /* fname ftype fmode */
219          unsigned int   __reserve4;        /* n/a */
220
221          /* note 1: values are: __TEXT, __BINARY, __RECORD
222             note 2: values are: __READ, __WRITE, __APPEND, __UPDATE
223                     these values can be added together to determine
224                     the return value; for example, a file opened with
225                     a+ will have the value __READ + __APPEND.
226             note 3: total block size of the file, including ASA
227                     characters as well as RDW information
228             note 4: maximum record length of the data only (includes
229                     ASA characters but excludes RDW information).
230          */
231       };
232