CICS Transaction failed with abend U4038 - cobol

This is CICS COBOL Program :-
IDENTIFICATION DIVISION.
PROGRAM-ID. ELECPRG.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INFL ASSIGN TO INFLDD
ORGANIZATION IS LINE SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS FS.
DATA DIVISION.
FILE SECTION.
FD INFL.
01 ELEC-REC.
05 P-NUM PIC X(5).
05 FILLER PIC X(1).
05 C-NAME PIC X(10).
05 FILLER PIC X(1).
05 C-UNIT PIC X(4).
WORKING-STORAGE SECTION.
COPY ELECMAP.
01 WS-MSG PIC X(20) VALUE 'BILL PROD DB UPDATE'.
01 FS PIC 9(2).
PROCEDURE DIVISION.
000-MAIN.
MOVE LOW-VALUES TO ELBILLI, ELBILLO
PERFORM 100-SEND-MAP.
PERFORM 200-RECEIVE-MAP.
PERFORM PROCESS-DATA.
PERFORM FILE-FUNC.
PERFORM 100-SEND-MAP.
PERFORM 300-RETURN.
STOP RUN.
100-SEND-MAP.
EXEC CICS
SEND
MAP('ELBILL') MAPSET('ELECMAP')
ERASE
END-EXEC.
200-RECEIVE-MAP.
EXEC CICS
RECEIVE
MAP('ELBILL') MAPSET('ELECMAP')
END-EXEC.
PROCESS-DATA.
MOVE CUSNOI TO CUSNOO.
MOVE NAMEI TO NAMEO.
MOVE UNITSI TO UNITSO.
MOVE UNITSI TO BILLO.
MOVE WS-MSG TO MSGO.
FILE-FUNC.
OPEN OUTPUT INFL.
DISPLAY 'OPEN FILE STATUS IS' FS.
MOVE CUSNOI TO P-NUM.
MOVE NAMEI TO C-NAME.
MOVE UNITSI TO C-UNIT.
WRITE ELEC-REC.
DISPLAY 'WRITE FILE STATUS IS' FS.
CLOSE INFL.
DISPLAY 'CLOSE FILE STATUS IS' FS.
300-RETURN.
EXEC CICS
RETURN
END-EXEC.
Mine compile jcl :-
//CICSCOB JOB CLASS=A,MSGCLASS=A,NOTIFY=&SYSUID,MSGLEVEL=(1,1)
//PROCLIB JCLLIB ORDER=DFH320.CICS.SDFHPROC
//STEP01 EXEC PROC=DFHYITVL,
// INDEX='DFH320.CICS',
// AD370HLQ='IGY410',
// LE370HLQ='CEE',
// PROGLIB='DFH320.CICS.SDFHLOAD',
// DSCTLIB='DFH320.CICS.SDFHMAC'
//TRN.SYSIN DD DISP=SHR,DSN=RAHUL.COBOL.PROGRAM(ELECPRG)
//INFLDD DD DSN=RAHUL.CICS.OUTPUT,DISP=SHR
//LKED.SYSIN DD *
NAME ELECPRG(R)
/*
Compilation complete a condition code = 0004 , few warnings.
But when I execute the transaction in CICS it terminates with CICS Transaction ELEC failed with abend U4038.
I don't understand the nature of this abend. I just want to update dataset RAHUL.CICS.OUTPUT from my CICS screen input. provided the output file location. Without the file use program is working fine , no abend occurs.

This program is a combination of COBOL file control commands and CICS SEND / RECEIVE MAP commands. COBOL file commands such as OPEN, READ, WRITE and CLOSE are not supported in a CICS transaction.
In a CICS program you have to use the CICS API as documented here https://www.ibm.com/docs/en/cics-ts/5.5?topic=programs-understanding-file-control

Related

Error IGZ0035S when attempting to open an output dataset in COBOL

I have created two datasets PRT-DONE and PRT-LINE in output. But when I am submitting job it is showing unsuccessful opening of PRT-DONE output; PRT-LINE is working fine.
I think it cannot open the datasets PRT-DONE. Looks like opening error of the output PRTDONE. When I was removing that open statement there was only condition code error.
Error:
IGZ0035S There was an unsuccessful OPEN or CLOSE of file PRTDONE in program ADDONE at relative location X'318'.
IDENTIFICATION DIVISION.
PROGRAM-ID. ADDONE.
AUTHOR. STUDENT.
*
ENVIRONMENT DIVISION.
*
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT PRT-LINE ASSIGN TO PRTLINE.
SELECT PRT-DONE ASSIGN TO PRTDONE.
DATA DIVISION.
FILE SECTION.
FD PRT-LINE RECORD CONTAINS 80 CHARACTERS RECORDING MODE F.
01 PRT-REC PIC X(80) VALUE SPACES.
FD PRT-DONE RECORD CONTAINS 80 CHARACTERS RECORDING MODE F.
01 PRT-REC-DONE.
05 PRT-DATE PIC X(8) VALUE SPACES.
05 FILLER PIC X(1) VALUE SPACES.
05 PRT-TIME PIC X(4) VALUE SPACES.
05 FILLER PIC X(2) VALUE SPACES.
05 PRT-COMMENT PIC X(27) VALUE SPACES.
05 FILLER PIC X(2) VALUE SPACES.
05 PRT-MY-NAME PIC X(36) VALUE SPACES.
WORKING-STORAGE SECTION.
01 PGM-VARIABLES.
05 PGM-COUNT PIC 9(05).
01 YYYYMMDD PIC 9(8).
01 INTEGER-FORM PIC S9(9).
01 REFMOD-TIME-ITEM PIC X(8).
****************************************************************
* PROCEDURE DIVISION *
****************************************************************
PROCEDURE DIVISION.
*
A000-START.
OPEN OUTPUT PRT-LINE.
PERFORM A000-COUNT 10 TIMES.
PERFORM A000-DONE.
CLOSE PRT-LINE.
STOP RUN.
*
A000-COUNT.
ADD 1 TO PGM-COUNT.
* DISPLAY PGM-COUNT.
WRITE PRT-REC FROM PGM-COUNT.
*
A000-DONE.
OPEN OUTPUT PRT-DONE.
MOVE SPACES TO PRT-REC-DONE.
ACCEPT REFMOD-TIME-ITEM FROM TIME.
MOVE FUNCTION CURRENT-DATE(1:8) TO YYYYMMDD.
MOVE YYYYMMDD TO PRT-DATE.
MOVE REFMOD-TIME-ITEM (1:4) TO PRT-TIME.
MOVE "My first z/OS COBOL program" TO PRT-COMMENT.
WRITE PRT-REC-DONE.
CLOSE PRT-DONE.
JCL:
//ADD1JCL JOB 1,NOTIFY=&SYSUID
//*****************/
//COBRUN EXEC IGYWCL
//COBOL.SYSIN DD DSN=&SYSUID..SOURCE(ADD1CBL),DISP=SHR
//LKED.SYSLMOD DD DSN=&SYSUID..LOAD(ADD1CBL),DISP=SHR
//*****************/
// IF RC = 0 THEN
//*****************/
//RUN EXEC PGM=ADD1CBL
//STEPLIB DD DSN=&SYSUID..LOAD,DISP=SHR
//PRTDONE DD DSN=Z12441.OUTPUT(PRTDONE),DISP=SHR,OUTLIM=15000
//PRTLINE DD DSN=Z12441.OUTPUT(PRTLINE),DISP=SHR,OUTLIM=15000
//SYSOUT DD SYSOUT=*,OUTLIM=15000
//CEEDUMP DD DUMMY
//SYSUDUMP DD DUMMY
//*****************/
// ELSE
// ENDIF
I assume your output data set Z12441.OUTPUT is of type PDS not PDS/E. You're trying to write to two members in the same PDS in parallel, which is not supported. In your job's output, you probably see a message IEC143I 213-30,.... Where 213 is the ABEND code which points to a problem with the OPEN service, and 30 is the return code. The explanation of messsage IEC143I can be found here Message description. The explanation for reason code 30 sais:
An attempt was made to open a partitioned data set (PDS) for OUTPUT,DISP=SHR. The PDS is already open in this condition, and a DCB is already open for output to the data set. The data set might be on the same system or on another system that is sharing the volume. Access was not serialized before the attempt to open the data set.
You need to allocate two distinct output data sets, one for PRTDONE, and one for PRTLINE. Two members of the same PDS are not two distinct data sets.
Note that PDS/E data sets allow multiple concurrent opens for output to different members, with some restrictions. I would advise to not get used to opening for output multiple members of the same PDS or PDS/E at the same time. Rather use PS data sets than PDS members for output. One reason being the restartability of jobs. With PS data sets, you can simply delete and reallocate the data set within a job, and then rerun the job. It is more complex to handle restartability with PDS members.

COBOL: Can a GDG file descriptor (FD) reference multiple generations?

I have a program which reads a GDG file and moves data to working storage. I am interested to know if it can be made to repeat this process for multiple generations of the GDG using a reference to the file definition. Perhaps there is a way to use subscripts on the file definition? My thought is there must be a method to move different file definitions into a reference variable from which to access the files.
Code Sample based on suggested, setenv solution
FILE-CONTROL.
SELECT DATAIN ASSIGN TO UT-S-DATAIN.
DATA DIVISION.
FILE-SECTION.
FD DATAIN
BLOCK CONTAINS 0 RECORDS
RECORD CONTAINS 133 CHARACTERS
LABEL RECORDS ARE STANDARD
DATA RECORD IS DATA-REC.
01 DATA-REC PIC X(133).
WORKING-STORAGE SECTION.
01 ENV-VARS.
02 ENV-NAME PIC X(9).
02 ENV-VALUE PIC X(100).
02 ENV-OVERWRITE PIC S9(8) COMPUTATIONAL VALUE 1.
PROCEDURE DIVISION.
MOVE Z"DATAIN" TO ENV-NAME
MOVE Z"DSN(PROGRAMMER.TEST.GDGFILE(-1)),SHR" TO ENV-VALUE
MOVE 1 TO ENV-OVERWRITE
CALL "setenv" USING ENV-NAME ENV-VALUE ENV-OVERWRITE.
Notes
Pay special attention when moving DSN value to ENV-VALUE. On my first swing I left out the closing parentheses, most likely because of JCL muscle memory.
Be sure to empty out your DD statement in JCL/Step.
In mainframe COBOL, the FD refers to a SELECT which refers to a DD statement attached to the EXEC PGM statement for your program in the invoking JCL. The DD statement may refer to one or many GDGs. This is determined at compile time.
What I think you are asking for is dynamic allocation of a file at runtime. There are a couple of ways to accomplish that, one is BPXWDYN.
Identification Division.
Program-ID. SOMETEST.
Environment Division.
Input-Output Section.
File-Control.
Select MY-FILE Assign SYSUT1A.
Data Division.
File Section.
FD MY-FILE
Record 80
Block 0
Recording F.
01 MY-FILE-REC PIC X(080).
Working-Storage Section.
01 CONSTANTS.
05 BPXWDYN-PGM PIC X(008) VALUE 'BPXWDYN '.
05 ALCT-LIT-PROC PIC X(035)
VALUE 'ALLOC FI(SYSUT1A) SHR MSG(WTP) DSN('.
05 FREE-LIT-PROC PIC X(016)
VALUE 'FREE FI(SYSUT1A)'.
05 A-QUOTE PIC X(001) VALUE "'".
01 WORK-AREAS.
05 WS-DSN PIC X(044) VALUE 'MY.GDG.BASE'.
05 WS-GDG-NB PIC 999 VALUE ZEROS.
05 BPXWDYN-PARM.
10 PIC S9(004) COMP-5 VALUE +100.
10 BPXWDYN-PARM-TXT PIC X(100).
Procedure Division.
* Construct the allocation string for BPXWDYN.
MOVE SPACES TO BPXWDYN-PARM-TXT
STRING
ALCT-LIT-PROC
DELIMITED SIZE
WS-DSN
DELIMITED SPACE
'(-'
DELIMITED SIZE
WS-GDG-NB
DELIMITED SIZE
')'
DELIMITED SIZE
INTO
BPXWDYN-PARM-TXT
END-STRING
CALL BPXWDYN-PGM USING
BPXWDYN-PARM
END-CALL
IF RETURN-CODE = 0
CONTINUE
ELSE
[error handling]
END-IF
[file I/O with MY-FILE]
MOVE SPACES TO BPXWDYN-PARM-TXT
MOVE FREE-LIT-PROC TO BPXWDYN-PARM-TXT
CALL BPXWDYN-PGM USING
BPXWDYN-PARM
END-CALL
IF RETURN-CODE = 0
CONTINUE
ELSE
[error handling]
END-IF
GOBACK.
This is just freehand, so there may be a syntax error, but I hope I've made the idea clear.
There is another technique, using the C RTL function setenv, documented by IBM here. It looks like it might be simpler but I've never done it that way.

COBOL input file to output file MAXCC(Error return code)=0012

I've been trying to read my input and write it to output file but can't find any mistakes in code. The JCL I'm submiting is good, because it was written by my mainframe lecturer, so I know the problem is somewhere in COBOL code... double checked everything, tried to find something with him in class - worthless... Line alignment, spacing, etc. are Ok I believe.
IDENTIFICATION DIVISION.
PROGRAM-ID. NAME.
AUTHOR. MYNAME.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT INPUT10 ASSIGN TO INPUTFIL.
SELECT OUTPUT10 ASSIGN TO OUTFIL.
DATA DIVISION.
FILE SECTION.
FD INPUT10
BLOCK CONTAINS 0 RECORDS
RECORDING MODE IS F
RECORD CONTAINS 80 CHARACTERS.
01 PLAYER-DETAILS.
03 PLAYER-ID PIC 9(07).
03 PLAYER-NAME.
05 NAME PIC X(08).
05 INITIALS PIC A(02).
03 PLAYER-BDAY PIC 9(08).
03 PLAYER-NR PIC 9(02).
FD OUTPUT10
BLOCK CONTAINS 0 RECORDS
RECORDING MODE IS F
RECORD CONTAINS 80 CHARACTERS.
01 OUTPUT-DETAILS.
03 OUTPUT-ID PIC 9(07).
03 OUTPUT-NAME.
05 O-NAME PIC X(08).
05 O-INITIALS PIC A(02).
03 OUTPUT-BDAY PIC 9(08).
03 OUTPUT-NR PIC 9(02).
WORKING-STORAGE SECTION.
01 WS-INDICATORS.
10 WS-EOF-IND PIC X(01) VALUE 'N'.
88 WS-END-OF-FILE VALUE 'Y'.
PROCEDURE DIVISION.
MAINFLOW.
OPEN INPUT INPUT10
OPEN OUTPUT OUTPUT10
READ INPUT10
AT END SET WS-END-OF-FILE TO TRUE
END-READ
PERFORM UNTIL WS-END-OF-FILE
MOVE PLAYER-ID TO OUTPUT-ID
MOVE NAME TO O-NAME
MOVE INITIALS TO O-INITIALS
MOVE PLAYER-BDAY TO OUTPUT-BDAY
MOVE PLAYER-NR TO OUTPUT-NR
READ INPUT10
AT END SET WS-END-OF-FILE TO TRUE
END-READ
WRITE OUTPUT10
END-WRITE
END-PERFORM
CLOSE INPUT10
CLOSE OUTPUT10
STOP RUN.
here is the code of JCL
//useridX JOB ,
// MSGCLASS=H,
// MSGLEVEL=(1,1),
// CLASS=A,
// REGION=0M,
// NOTIFY=&SYSUID
//COBOL1 EXEC IGYWCLG,REGION=50M,
// PARM.COBOL='TEST,RENT,APOST,OBJECT,NODYNAM,LIB,SIZE(1048376)'
//COBOL.STEPLIB DD DSN=IGY420.SIGYCOMP,
// DISP=SHR
//COBOL.SYSIN DD DISP=SHR,DSN=userid.KURS.COBOL(PROG2)
//GO.INPUTFIL DD DISP=SHR,DSN=userid.KURS.PLAYERS
//GO.OUTFIL DD DISP=SHR,DSN=userid.KURS.REPORT
and it works for other students, so I'm pretty sure the cause of maxcc=12 is COBOL's part
Any suggestions?
Thanks.
P.S. I cannot check my job logs - something is wrong with my mainframe account or mainframe itself. This is the main cause why I can't find the problem
OK - I have run this successfully after some code changes. You really need to get your output sorted - are you using the correct MSGCLASS. Check - do not assume.
Program errors:
Look at PROGRAM-ID
Look at record lengths and compare to what you describe the record lengths of the files
Look at what you are writing.
Improvements:
Always check your status after any file operation - OPEN READ WRITE CLOSE.
Your indentation is not good. If it is on your machine then take more care when posting.
The input file and output file is declared as Fixed and is of length 80.
But both input and output variables are of length less than 80. They have length of 27.So in player-details and output details add filler variable with length 80 - 27 = 53
Also make sure the input and output file length are 80.

The system detected a protection exception

I am trying to use the SORT feature of COBOL.
IDENTIFICATION DIVISION.
PROGRAM-ID. ******.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT IN-FILE ASSIGN TO IFILE.
SELECT OUT-FILE ASSIGN TO OFILE.
SELECT SORT-FILE ASSIGN TO SORTWK.
DATA DIVISION.
FILE SECTION.
SD SORT-FILE.
01 SORT-REC.
05 S-NAME PIC X(20).
05 S-ADDRESS PIC X(20).
05 S-ID PIC 9(9).
05 S-CREDITS PIC 99.
05 FILLER PIC X(29).
FD IN-FILE.
01 IN-REC.
05 IN-NAME PIC X(20).
05 IN-ADDRESS PIC X(20).
05 IN-ID PIC 9(9).
05 IN-CREDITS PIC 99.
05 FILLER PIC X(29).
FD OUT-FILE.
01 OUT-REC PIC X(80).
WORKING-STORAGE SECTION.
01 WS-WORK-AREA.
05 EOF-SW PIC X VALUE SPACES.
01 WS-DETAIL-LINES.
05 RPT-LINE.
10 OUT-NAME PIC X(20).
10 OUT-ADDRESS PIC X(20).
10 OUT-ID PIC 9(9).
10 OUT-CREDITS PIC 99.
10 FILLER PIC X(29) VALUE SPACES.
PROCEDURE DIVISION.
MAIN-RTN.
SORT SORT-FILE
ON ASCENDING KEY S-ID
INPUT PROCEDURE READ-RELEASE
OUTPUT PROCEDURE RETURN-WRITE.
STOP RUN.
OPEN-FILES-RTN.
OPEN INPUT IN-FILE.
OPEN OUTPUT OUT-FILE.
OPEN-FILES-RTN-EXIT. EXIT.
READ-RELEASE.
PERFORM OPEN-FILES-RTN.
PERFORM READ-INPUT
UNTIL EOF-SW = 'F'.
READ-RELEASE-RTN-EXIT. EXIT.
READ-INPUT.
READ IN-FILE
AT END MOVE 'F' TO EOF-SW.
RELEASE SORT-REC FROM IN-REC.
RETURN-WRITE.
MOVE SPACES TO EOF-SW.
PERFORM WRITE-FL
UNTIL EOF-SW = 'F'.
PERFORM CLOSE-FILES-RTN.
RETURN-WRITE-RTN-EXIT. EXIT.
WRITE-FL.
RETURN SORT-FILE RECORD INTO OUT-REC
AT END MOVE 'F' TO EOF-SW.
WRITE OUT-REC.
WRITE-FL-RTN-EXIT. EXIT.
CLOSE-FILES-RTN.
CLOSE IN-FILE OUT-FILE.
CLOSE-FILES-RTN-EXIT. EXIT.
I am able to compile this program but when it comes to execute, it gives the following error:
CEE3204S The system detected a protection exception (System Completion
Code=0C4). From compile unit SU98PGM6 at entry point SU98PGM6
at compile unit offset +0005517A at address 1F45517A.
I have searched about this error but I couldn't figure out what is causing this problem in my program.
I have made some changes after taking note of the comments, but am still getting the same problem with this changed code.
READ-RELEASE.
PERFORM OPEN-FILES-RTN.
PERFORM READ-INPUT
UNTIL EOF-SW = 'F'.
READ-RELEASE-RTN-EXIT. EXIT.
READ-INPUT.
READ IN-FILE
AT END MOVE 'F' TO EOF-SW
NOT AT END PERFORM PROCESS-INPUT.
PROCESS-INPUT.
MOVE IN-NAME TO S-NAME.
MOVE IN-ADDRESS TO S-ADDRESS.
MOVE IN-ID TO S-ID.
MOVE IN-CREDITS TO S-CREDITS.
RELEASE SORT-REC.
PROCESS-INPUT-RTN-EXIT. EXIT.
RETURN-WRITE.
MOVE SPACES TO EOF-SW.
PERFORM WRITE-FL
UNTIL EOF-SW = 'F'.
PERFORM CLOSE-FILES-RTN.
RETURN-WRITE-RTN-EXIT. EXIT.
WRITE-FL.
RETURN SORT-FILE RECORD INTO OUT-REC
AT END MOVE 'F' TO EOF-SW
NOT AT END PERFORM PROCESS-OUTPUT.
WRITE-FL-RTN-EXIT. EXIT.
PROCESS-OUTPUT.
MOVE S-NAME TO OUT-NAME.
MOVE S-ADDRESS TO OUT-ADDRESS.
MOVE S-ID TO OUT-ID.
MOVE S-CREDITS TO OUT-CREDITS.
WRITE OUT-REC.
PROCESS-OUTPUT-RTN-EXIT. EXIT.
Here is my JCL
//******** JOB 1,'*****',NOTIFY=*******
//JOBLIB DD DSN=*******.*******.*******,DISP=SHR
//STEP0 EXEC PGM=SU98PGM6
//IFILE DD DSN=*******.*******.*******.*******(*******),DISP=SHR
//SORTWK DD DSN=*******.*******.*******.*******,DISP=SHR
//OFILE DD DSN=*******.*******.*******.*******,
// DISP=(NEW,CATLG,DELETE),
// DCB=(BLKSIZE=0,LRECL=80,RECFM=FB),
// SPACE=(CYL,(1,1),RLSE),
// UNIT=SYSDA
/*
The output for the //SYSOUT DD can be confusing when using COBOL, SORT (DFSORT or SyncSORT) and Language Environment which may give you run-time messages, as they all use SYSOUT by default, and the messages will appear intermingled.
Fortunately, you can change the default behaviour, as shown here for DFSORT and Language Envrionment (there are many ways in LE to specify the option, the most flexible is a //CEEOPTS DD in your JCL): https://stackoverflow.com/a/29521423/1927206
COBOL itself has a compiler option, OUTDD. the value defaults to SYSOUT, but you can specify any OUTDD(xxxx)
OK, having seen your JCL and your comments about how a DISPLAY statement in your program affects the data, I've managed a partial reproduce.
I use DFSORT, and I don't get your exact behaviour so I'm going to assume you use SYNCSORT.
The behaviour I can get having removed the //SYSOUT DD from my JCL is this message:
IGZ0026W The SORT-RETURN special register was never referenced, but
the current content indicated the sort or merge operation in program
STOB87 on line number 46 was unsuccessful.
When I add the //SYSOUT back into the JCL, the program runs successfully.
When I take the //SYSOUT out and add a DISPLAY before the SORT, the program works. This is because if there is no //SYSOUT in the JCL the first DISPLAY which is executed will cause one to be dynamically created (the output will appear in the spool as though it were a separate JOB, with the same name and jobnumber).
In my case DFSORT is complaining about the missing //SYSOUT. With the DISPLAY, the //SYSOUT is not missing at the time DFSORT starts.
I have to assume that SYNCSORT is facing a similar issue, but the run-time COBOL message is not produced and SYNCSORT itself fails on the next RELEASE.
Although this seems like a simple and common issue, because we always copy a piece of JCL to make a new piece of JCL, //SYSOUT is always there.
Consult the Enterprise COBOL Programming Guide, Chapter 12 I think, and see how to use SORT-RETURN to confirm that the SORT completed successfully.
I'm pretty sure that if you include the //SYSOUT in your JCL you will no longer get the abend, whether or not you have a DISPLAY.
The reason for the high "offset" is that the abend processor is unable to identify the entry-point of your SORT product, so keeps searching backwards to find something it can identify, and locates your program entry-point and then calculates the incorrect offset. This can also happen when CALLing some Assembler programs.
Firstly, to your S0C4, which is a Protection Exception, which means you are attempting to access storage which doesn't "belong" to you for the access you want.
You are getting a S0C4 in program SU98PGM6. You have cunningly obliterated your PROGRAM-ID name when posting here, which probably hasn't helped.
SU98PGM6 is not your program. The abend (Abnormal End) is at offset X'0005517A' in the failing program. That means, from the "start" of the program (the Entry Point) the instruction at offset/displacement X'0005517A' is the one which attempted the bad thing. That offset, which in decimal is 348538, indicates a fairly large program. Your program is very small.
There are many ways that this can come about. For instance, you may have copied the JCL from somewhere else, and failed to change the EXEC PGM=. You may have a program of the same name as yours earlier in the STEPLIB concatenation. You may have compiled the wrong program. Etc.
When you get an abend, always confirm that the compile listing you have is for the program that abended. An easy and useful way to do this is:
01 W-WHEN-COMPILED PIC X(8)BX(8).
...
* where it can only be executed once:
MOVE WHEN-COMPILED TO W-WHEN-COMPILED
DISPLAY
"yourname COMPILED ON "
W-WHEN-COMPILED
"yourname" you replace with the text following PROGRAM-ID.
The output will be like this:
yourname COMPILED ON 11/24/15 10.35.26
That will match the date/time in the heading on each page of the compile listing.
If you run a program and don't get that output, or you get output but it is not the output expected, then you know your program is not the one running.
Now to your program.
You do not need to use input/output procedures to be able to SORT
You should always use the FILE STATUS clause of the SELECT statement, and always check the file-status fields (one per file) that you define, after each IO operation. Testing the file-status field for an input file will allow you to identify end-of-file without the need for the tortuous AT END/NOT AT END construct
If you use sort procedures, COBOL does the IO. If you don't, and use compiler option FASTSRT, your SORT product will do the IO, which will be much more efficient than COBOL.
Unless you are selecting or reformatting records, you don't need the sort procedures
Since you are using INTO, which does an implicit MOVE of the record, you don't need to also MOVE the data individually
COBOL, since compilers supporting the 1985 Standard, which I'm fairly sure you will have, have "scope terminators". Prior to that, the only scope-terminator was the full-stop/period. These days, use the explicit, specific scope-terminators when using "imperative statements" and for all conditional statements. In your case, replace use READ/END-READ, RETURN/END-RETURN
Only use full-stops/periods in the PROCEDURE DIVISION where they are required, and not on a line of code. This aids the moving/copying of code from one location to another
Use 88-level condition-names for tests, rather than literals. You can make the name exactly meaningful, so nobody ever has to wonder what 'F' means in a particular context
To simply SORT a file in a COBOL program, look at SORT ... USING ... GIVING... and use compiler option FASTSRT (if possible).
You are not yet aware of the implications of paragraphs (or SECTIONs) and the EXIT statement.
When using PERFORM or a SORT PROCEDURE execution is transferred to the code in the paragraph, and returns control when the next paragraph is reached.
Your "exit" paragraphs as you have coded are never used, but someone looking at the code will assume (if they are silly, and a lot of people will make the assumption) that you have used THRU and they'll stick in a GO TO the "exit" paragraph. Then they'll be surprised that the program behaves badly (if they're luck) and will eventually work out that they have used GO TO to transfer control out of the range of the PERFORM/PROCEDURE.
If your local standards enforce the use of exit-paragraphs, then you must use THRU in your PERFORM and PROCEDURE statements.
Exit-paragraphs are entirely useless, and do nothing but provide a target-label for a GO TO, meaning that someone in the future will likely use a GO TO for "convenience".
Here's your original program with the exit-paragraphs removed:
IDENTIFICATION DIVISION.
PROGRAM-ID. ******.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT IN-FILE ASSIGN TO IFILE.
SELECT OUT-FILE ASSIGN TO OFILE.
SELECT SORT-FILE ASSIGN TO SORTWK.
DATA DIVISION.
FILE SECTION.
SD SORT-FILE.
01 SORT-REC.
05 S-NAME PIC X(20).
05 S-ADDRESS PIC X(20).
05 S-ID PIC 9(9).
05 S-CREDITS PIC 99.
05 FILLER PIC X(29).
FD IN-FILE.
01 IN-REC.
05 IN-NAME PIC X(20).
05 IN-ADDRESS PIC X(20).
05 IN-ID PIC 9(9).
05 IN-CREDITS PIC 99.
05 FILLER PIC X(29).
FD OUT-FILE.
01 OUT-REC PIC X(80).
WORKING-STORAGE SECTION.
01 WS-WORK-AREA.
05 EOF-SW PIC X VALUE SPACES.
01 WS-DETAIL-LINES.
05 RPT-LINE.
10 OUT-NAME PIC X(20).
10 OUT-ADDRESS PIC X(20).
10 OUT-ID PIC 9(9).
10 OUT-CREDITS PIC 99.
10 FILLER PIC X(29) VALUE SPACES.
PROCEDURE DIVISION.
SORT SORT-FILE
ON ASCENDING KEY S-ID
INPUT PROCEDURE READ-RELEASE
OUTPUT PROCEDURE RETURN-WRITE
GOBACK
.
OPEN-FILES-RTN.
OPEN INPUT IN-FILE
OPEN OUTPUT OUT-FILE
.
READ-RELEASE.
PERFORM OPEN-FILES-RTN
PERFORM READ-INPUT
UNTIL EOF-SW = 'F'
.
READ-INPUT.
READ IN-FILE
AT END MOVE 'F' TO EOF-SW
END-READ
RELEASE SORT-REC FROM IN-REC
.
RETURN-WRITE.
MOVE SPACES TO EOF-SW
PERFORM WRITE-FL
UNTIL EOF-SW = 'F'
PERFORM CLOSE-FILES-RTN
.
WRITE-FL.
RETURN SORT-FILE RECORD INTO OUT-REC
AT END MOVE 'F' TO EOF-SW
END-RETURN
WRITE OUT-REC
.
CLOSE-FILES-RTN.
CLOSE IN-FILE OUT-FILE
.
I've also changed the STOP RUN to GOBACK, which is much more flexible, and removed your first paragraph-name, as it is unnecessary and for people new to COBOL implies too much (COBOL itself has no concept of "main" as it may be pertinent in other languages you may know).

Error in rewrite cobol

I have the code,
IDENTIFICATION DIVISION.
PROGRAM-ID. SAMPLE3.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT EMP-SALARY ASSIGN TO 'input.txt'
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD EMP-SALARY.
01 NEWFILE.
05 FS-EMPNO PIC 9(6).
05 FS-NAME PIC 9(4).
05 FILLER PIC X(63).
WORKING-STORAGE SECTION.
01 WS-EOF PIC A(1) VALUE "N".
PROCEDURE DIVISION.
MAIN-PARA.
OPEN I-O EMP-SALARY
PERFORM READ-PARA THRU READ-PARA-EXIT UNTIL WS-EOF="Y"
STOP RUN.
MAIN-PARA-EXIT.
EXIT.
READ-PARA.
READ EMP-SALARY
AT END
MOVE "Y" TO WS-EOF
NOT AT END
IF FS-EMPNO > 10000
MOVE '1000' TO FS-NAME
REWRITE NEWFILE
DISPLAY " RECORD " NEWFILE
END-IF
END-READ.
READ-PARA-EXIT.
EXIT.
I got the error read statement should be executed first Status=43, and implicit close of file.
This program is to rewrite a record in a file. what is the reason for this error.
It is best to include FILE STATUS processing for any files you use in a program, and always test the value after an IO.
If that is the code you are running, you must have an OPEN failing, a READ failing, and the REWRITE deciding that it just can't go on. Check that it is the code that you are running.
Can you show the version of GnuCOBOL you are running, and the OS you are running on, include the FILE STATUS in your program and test the values, and also include an explicit CLOSE of your file, which is always good practice.
See if structuring your program like this simplifies:
PROCEDURE DIVISION.
OPEN I-O EMP-SALARY
* do file status checking here
PERFORM READ-PARA
PERFORM PROCESS-PARA UNTIL END-OF-INPUT-FILE
* END-OF-INPUT-FILE (make the name relevant to your file) is an 88 on the FILE STATUS
* filed for that file
* close the file
* do file status checking here
STOP RUN
.
READ-PARA.
READ EMP-SALARY
* do file status checking here
PROCESS-PARA.
IF FS-EMPNO > 10000
MOVE '1000' TO FS-NAME
PERFORM UPDATE-RECORD
END-IF
PERFORM READ-PARA
.
UPDATE-RECORD.
REWRITE NEWFILE
* do file status checking here
DISPLAY " RECORD " NEWFILE
.

Resources