This article discusses one cause of a U3331 abend in module QUIKIO, and a little information on user controlled I/O.
The first place to look for clues when any abend occurs is SYSPRINT, scanning for error messages.
Adding LIST=YES,LISTOPT=YES,TRACECT=1 to the OPTIONs in the program
and TRACE ALL before the first executable statement helps diagnose the problem:
This is the TRACE output:
STMT 21 TRAC 2700900A
STMT 27 GET 27009018
STMT 28 MOVE 27009030
STMT 30 GET 27009048
ERR259. GET ISSUED FOR INF FILE AFTER END OF FILE
Reflecting this section of code:
(27) GET INF
(28) MOVE INF1-80 TO WST1-80
(30) 010 GET INF ATEND 901
The message was our clue: ERR259. GET ISSUED FOR INF FILE AFTER END OF FILE
ERR259 is issued because there are no input records, so the second GET is past end of file.
Confusion remained because the program includes an ATEND parameter on the GET statement at line 30.
The user expected this to cause a branch to the label 901 on that GET, and then wrap up the program.
The problem is there are multiple GET statements in the program, but the one at line 27 does not include an ATEND parameter.
The ATEND parameter must exist on all GET statements or it is ignored.
Once the ATEND parameter was added to the GET statements on line 27, the program functioned as expected.
The bottom line is ATEND is an all or nothing operand.
If you specify it on any GET statement, it must be specified on all GET statements.