MODULE 8 · SEQUENTIAL FILES · 4/8

FILE STATUS and return codes

15 min30 XPExercise

Every I/O statement can fail. The dataset might not exist, the job might have the wrong DD, the disk might be full. Production code checks the outcome of every OPEN, READ, WRITE and CLOSE, and COBOL reports that outcome through a two-character file status.

Declaring it

Add FILE STATUS IS to the SELECT and declare the field in WORKING-STORAGE as PIC XX. After each I/O statement on that file, the runtime stores the result code in it:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. STATDEMO.
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT RATE-FILE ASSIGN TO RATES
               ORGANIZATION IS LINE SEQUENTIAL
               FILE STATUS IS WS-RATE-STATUS.
       DATA DIVISION.
       FILE SECTION.
       FD  RATE-FILE.
       01  RATE-REC           PIC X(20).
       WORKING-STORAGE SECTION.
       01  WS-RATE-STATUS     PIC XX.
       PROCEDURE DIVISION.
           OPEN INPUT RATE-FILE
           DISPLAY "OPEN:  " WS-RATE-STATUS
           READ RATE-FILE
           DISPLAY "READ:  " WS-RATE-STATUS " " RATE-REC
           READ RATE-FILE
           DISPLAY "READ:  " WS-RATE-STATUS
           READ RATE-FILE
           DISPLAY "READ:  " WS-RATE-STATUS
           CLOSE RATE-FILE
           DISPLAY "CLOSE: " WS-RATE-STATUS
           STOP RUN.

With DD_RATES pointing at a one-record dataset:

OPEN:  00
READ:  00 EUR 1.0000
READ:  10
READ:  46
CLOSE: 00

With DD_RATES pointing at a dataset that does not exist:

OPEN:  35
READ:  47
READ:  47
READ:  47
CLOSE: 42

Look at the second run carefully. Nothing stopped the program. Once you declare a FILE STATUS, the runtime assumes you are handling errors, so a failed OPEN is simply recorded and the program ploughs on. Without a FILE STATUS clause, the same failed OPEN ends the run with a runtime error instead (in GnuCOBOL, libcob: error: file does not exist (status = 35)). Declaring a status and then ignoring it is the worst of both.

The codes you will meet

The first digit is the category, the second the detail.

Code Meaning
00 Success
05 OPEN of an OPTIONAL file that is not there (not an error)
10 End of file: no more records
2x Invalid key (indexed files, later)
30 Permanent I/O error (hardware, space)
35 OPEN of a file that does not exist
37 OPEN mode not allowed for this file
39 File attributes do not match the program (e.g. record length)
41 / 42 OPEN of a file already open / CLOSE of a file not open
46 READ after end of file was already reached
47 / 48 / 49 READ, WRITE or REWRITE in the wrong OPEN mode

Checking it

Give the status field 88-level names and test it after each operation:

       01  WS-IN-STATUS       PIC XX.
           88  IN-OK          VALUE "00".
           88  IN-EOF         VALUE "10".

With a FILE STATUS declared, a READ without AT END is fine: status 10 tells you it hit the end, and anything other than 00 or 10 is a real error.

Failing the job step

When a batch program cannot continue, it should say why and end with a non-zero return code. Move a value to the special register RETURN-CODE before STOP RUN:

           IF NOT IN-OK
               DISPLAY "OPEN FAILED: STATUS " WS-IN-STATUS
               MOVE 12 TO RETURN-CODE
               STOP RUN
           END-IF

On z/OS the return code becomes the step's condition code, and the JCL uses it to skip later steps that depend on this one. Common shop conventions: 0 fine, 4 warning, 8 error, 12 or 16 severe.

On the job

"Check every file status" is on every COBOL code-review checklist. Many shops have a standard error paragraph that displays the program name, file name, operation and status, then sets the return code, so the operator reading the job log at 2 a.m. knows exactly what failed.

Your task

Write a small utility that counts the records in any dataset, and fails cleanly if the dataset is missing.

The input is assigned to DD name INFILE (line sequential, records up to 80 characters; content does not matter).

  • Declare a FILE STATUS for the file and check it after the OPEN and after every READ.
  • If the OPEN fails, display OPEN FAILED: STATUS followed by the status, set the return code to 12 and stop.
  • If a READ returns anything other than 00 or 10, display READ FAILED: STATUS and the status, set the return code to 16 and stop.
  • Otherwise count the records and display:

    RECORDS: 00003

For a missing dataset the output is:

OPEN FAILED: STATUS 35

and the program must end with return code 12.

fixed format
Run your program to see its output here. The first visible test's input and datasets are used.
Submit to grade your program against every test.