IKXDYN.HLP 1991 June 19 Specifications for Kermit-CICS I/O Drivers Files of filetype PGM and SPOOL, as well as native data sets, are not handled directly by Kermit, but rather by "I/O drivers". Filetype PGM is used for data pipes, in general, and the others are simply special cases. The data object "name.PGM" would be moderated by CICS program "name", and all I/O operations are performed by invoking the program with a COMMAREA consisting of the Kermit File Access Block (FAB). See below for the details of the FAB. SPOOL files and native data sets are handled by a special driver called IKXDYNAL, but the calling sequence is the same for all drivers. Drivers must be reentrant. A driver could be written to handle only input or only output or both. Upon entry to the driver, FABCOMM must contain an 8-byte operation code. There must be a completion code in FABRESP upon return. It should be in the style of EIBRCODE. FABFID has the file identifier. FABFLGS identifies the type of driver: flag FABFPGM is set for ordinary pipes, and flag FABFSPL for SPOOL files and native data sets. The remainder of FABFID depends upon FABFLGS. For ordinary pipes, the name of the driver is given in FABFNAM, and an optional parameter is given in FABFUID. For files driven by IKXDYNAL, the situation is more complicated. If FABFUID begins with an apostrophe ('), the file is an external data set specified by name; in that case, FABFNAM has the following: 1. F: Ptr to current QFN buffer 2. H: Offset to display form of QFN 3. H: Length of display form Note: the QFN buffer has the fully-qualified DSN, padded with blanks to a length of 54. Since there appears to be no means of dynamic allocation under VSE, only MVS data set names need be considered here. The QFN may be either a normal sequential DSN or may be the name of a PDS followed by a member name in parentheses, as in P.D.S(MEMBER). For IKXDYNAL, if FABFUID is anything else, the file is a spool file with class given by FABFUID and name given by FABFNAM. Upon opening a file, a driver must allocate any needed storage and save the pointer in FABUWORD. At closing, this storage must be released. FABIOF contains 0 if the file is for input, 1 if for output. ----------------------- Layout of FAB ----------------------------- FABD DSECT , FABRESP DS XL6 Saved response code FABNORD DS H Byte count of last transfer FDBD DS 0F Beginning of short descriptor FDBBUFF DS A Buffer ptr FDBBSIZ DS F Max record length FDBRCF DS C Record format FDBFLGS DS X Flags FDBACTV EQU X'80' File is already open * SVATT EQU X'40' Preserve attributes * APPN EQU X'10' DISP=MOD FDBLRC DS H File record length FDBSIZE DS F File size in Kbytes FDBCOP EQU *-FDBD Length to copy for OPEN FDBDATE DS XL7 Time stamp: packed yyyymmddhhmmss FABFID DS 0CL13 File designator FABFLGS DS X Flags indicating type of file FABFMAIN EQU X'01' Flag for MAIN TS queue FABFTS EQU X'02' Flag for TS queue FABFTD EQU X'04' Flag for TD queue FABFPGM EQU X'08' Flag for pipe file FABFSPL EQU X'10' Flag for spool file FABFTAK EQU X'20' Flag for internal Kermit file FABFUID DS CL8 User name FABFNAM DS CL8 File name FABRN DS H Record number FDBNREC DS H Number of records FDBFL2 DS X More flags FDBXRCF DS X External format flags FDBXLRC DS H External old LRECL FDBXBLK DS H External old block size FDBINFO EQU *-FDBD Length of info returned FABIOF DS X More flags FABLRTR DS F Record length for truncation FABUWORD DS F Reserved for user applications FABCOMM DS CL8 Command name .* CLOSE Close file named in FABFID .* CWD Set new user directory or QFN prefix: string is at .* FABFID+2 with 2-byte unsigned length at FABFID .* DELETE Delete file named in FABFID .* OPEN I Open file named in FABFID for input .* OPEN O Open file named in FABFID for output .* READ Read a record from (already open) file .* READ TD Read a record from (already open) TD queue .* READ TS Read a record from (already open) TS queue .* TEST Check whether file named in FABFID exists .* WRIT TD Write a record to (already open) TD queue .* WRIT TS Write a record to (already open) TS queue .* WRITE Write a record to (already open) file ------------------- Scenarios that I/O drivers must handle ------------- Not all of the possible FABCOMM codes shown above would be passed to an I/O driver. The following sequences of calls illustrate the actual codes to be expected. ----------------------- S E N D ------------------------ 1. call with FABCOMM=CL8'TEST'. The file attributes should be set in FDBXRCF, FDBXLRC, and FDBXBLK upon return (in the format of a DCT SDSCI). BLOCKSIZE is needed only if RECFM=U, LRECL only if RECFM is not U, and RECFM always. Ideally, a driver should also figure out how big the file is and save the result in FDBSIZE and put the time stamp in FDBDATE and the number of records in FDBNREC, but this isn't really necessary. If the file doesn't exist, a non-zero FABRESP should be set, and the other items can obviously be skipped. 2. call with FABCOMM=CL8'OPEN I'. The file should be allocated and opened. If there is any problem at all, a non-zero FABRESP should be set upon return. The file attributes should be set up, just as for 'TEST'. 3. call with FABCOMM=CL8'READ'. FDBBUFF points to the data buffer, FABNORD gives length of buffer. On return, FABNORD should have the actual byte count read. If FABRESP contains x'01' in the 1st byte on return, that signals end-of-file; any other non-zero code is deemed an I/O error. There should be some error code if 'READ' is used for an output file (as indicated by FABIOF) or if the file has not been opened. 4. call with FABCOMM=CL8'CLOSE'. The file should be closed and freed. -------------------- R E C E I V E --------------------- 1. call with FABCOMM=CL8'TEST'. This is the same as #1 under SEND. If 'TEST' indicates that the file already exists, this step might, in principle, be repeated with different names in order to find a non-duplicate, but Kermit just gives up at present. The step *will* be repeated if Kermit is told to verify storage space. 2. call with FABCOMM=CL8'OPEN O'. For spool output, the file (by definition) does not exist yet. Also, the output attributes may be universally predefined (e.g., V/205 or F/80). For disk output (possible under MVS), the action depends on the value of FDBFLGS and on whether the file already exists. If it does not, or if neither APPN nor SVATT is set in FDBFLGS, then FDBLRC must be used for the output LRECL, and FDBRCF for the output RECFM, but BLKSIZE must be defaulted (FDBRCF "F" means "FB", and "V" means "VB"). If the file exists, but APPN is not set, then the output must overwrite the original file. If APPN is set, the output must be appended. In any case, the LRECL and RECFM used must be left in FDBLRC and FDBRCF. The file should be allocated and opened when the attributes have been settled. Regardless of whether all this works, a non-zero FABRESP should be set upon return. 4. call with FABCOMM=CL8'WRITE'. FDBBUFF points to the data buffer, FABNORD gives length of buffer, as does FDBBSIZ. If FABRESP contains x'10' in the 1st byte on return, that signals disk-full; any other non-zero code is deemed an unknown I/O error. There should be some error code if 'WRITE' is used for an input file (as indicated by FABIOF) or if the file has not been opened. 5. call with FABCOMM=CL8'CLOSE'. The file should be closed and freed. --------------------- D E L E T E ---------------------- 1. call with FABCOMM=CL8'DELETE'. The file should be purged or deleted as appropriate. If it doesn't exist or can't be deleted, some sort of error code should be set.