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