View previous topic :: View next topic
|
Author |
Message |
hernikiten
New User
Joined: 08 Apr 2005 Posts: 23 Location: india
|
|
|
|
Scenario
I have two programs A (transid JI51) and B(transid JI52). A is calling B through LINK.
PROG A is like this:
Code: |
LINKAGE SECTION.
01 DFHCOMMAREA PIC X(10).
PROCEDURE DIVISION.
A000-MAIN-PARA.
EXEC CICS IGNORE CONDITION
MAPFAIL
END-EXEC.
MOVE DFHCOMMAREA TO WS-COMMAREA.
IF EIBCALEN = 0
MOVE 'FIRSTT' TO WS-COMMAREA
PERFORM B0001-SEND-MAP-PARA
PERFORM B0002-RETURN-PARA
ELSE
IF EIBAID = DFHENTER
PERFORM B0003-RECEIVE-MAP-PARA
PERFORM B0005-PROCESS-REQUEST-PARA
END-IF
IF EIBAID = DFHPF3
PERFORM B0007-EXIT-PARA
END-IF
B0001-SEND-MAP-PARA.
EXEC CICS SEND
MAP('FISCAL')
MAPSET('JIMP051')
FREEKB
END-EXEC.
B0002-RETURN-PARA.
EXEC CICS
RETURN
TRANSID('JI51')
COMMAREA(WS-COMMAREA)
LENGTH(10)
END-EXEC.
B0003-RECEIVE-MAP-PARA.
EXEC CICS
RECEIVE
MAP('FISCAL')
MAPSET('JIMP051')
END-EXEC.
B0005-PROCESS-REQUEST-PARA.
PERFORM B0056-CALL-SUBROUTINES.
B0007-EXIT-PARA.
MOVE 'THANK YOU ...BYE.. ' TO WS-MESSAGE.
EXEC CICS SEND TEXT
FROM(WS-MESSAGE)
LENGTH(21)
END-EXEC.
EXEC CICS RETURN
END-EXEC.
B0056-CALL-SUBROUTINES.
EXEC CICS LINK
PROGRAM('JIPGM052')
COMMAREA(WS-SUB-COMMAREA)
LENGTH(18)
END-EXEC. |
PROG2 is like this:
Code: |
PROCEDURE DIVISION.
A000-MAIN-PARA.
EXEC CICS IGNORE CONDITION
MAPFAIL
INVREQ
END-EXEC.
IF EIBCALEN = 0
MOVE LOW-VALUES TO FIS544O
MOVE 'FIRST TIME' TO WS-COMMAREA
PERFORM B0005-SEND-MAP-PARA
PERFORM B0006-RETURN-PARA
ELSE
IF EIBAID = DFHPF3
PERFORM B0004-EXIT-PARA
ELSE
PERFORM B0006-RETURN-PARA
END-IF
END-IF.
B0005-SEND-MAP-PARA.
EXEC CICS SEND
MAP('FIS544')
MAPSET('JIMP051')
ERASE
FREEKB
END-EXEC.
B0006-RETURN-PARA.
EXEC CICS RETURN
TRANSID('JI52')
COMMAREA(WS-COMMAREA)
LENGTH (20)
END-EXEC.
B0004-EXIT-PARA.
MOVE SPACES TO WS-MESSAGE.
MOVE 'SUCCESS :) ' TO WS-MESSAGE.
EXEC CICS SEND TEXT
FROM(WS-MESSAGE)
LENGTH(30)
END-EXEC.
EXEC CICS RETURN
END-EXEC. |
Problem - Program A calls B. B is supposed to send a map and go return in pseudoconversational mode. If the user presses PF3 it should return control to A. But this is not happening as soon as A calls B, B returns control back to A.
I know it may seem confusing. If you guys could see any mistake in the code, Please advice? I don't have Xpeditor to debug it.
Thanks. |
|
Back to top |
|
|
dbzTHEdinosauer
Global Moderator
Joined: 20 Oct 2006 Posts: 6966 Location: porcelain throne
|
|
|
|
comment removed by poster |
|
Back to top |
|
|
Bill O'Boyle
CICS Moderator
Joined: 14 Jan 2008 Posts: 2501 Location: Atlanta, Georgia, USA
|
|
|
|
You can't move DFHCOMMAREA to WS-COMMAREA before checking EIBCALEN. You're setting yourself up for a S0C4 Protection Exception.
Regards, |
|
Back to top |
|
|
Robert Sample
Global Moderator
Joined: 06 Jun 2008 Posts: 8696 Location: Dubuque, Iowa, USA
|
|
|
|
Okay, major confusion here -- there is a reason the Code button exists just below the subject line. Click it, paste your code, click it again.
In the meantime, you say tx JI51 maps to program A. This program checks DFHCOMMAREA length for zero, sends a map, then returns to JI51. When the enter key is hit, program A receives the map and links to program B -- using a COMMAREA. The key code in program B is
Code: |
IF EIBCALEN = 0
MOVE LOW-VALUES TO FIS544O
MOVE 'FIRST TIME' TO WS-COMMAREA
PERFORM B0005-SEND-MAP-PARA
PERFORM B0006-RETURN-PARA
ELSE
IF EIBAID = DFHPF3
PERFORM B0004-EXIT-PARA
ELSE
PERFORM B0006-RETURN-PARA
END-IF
END-IF. |
We know EIBCALEN is not zero in program B ... because you passed a COMMAREA from program A. Fail the IF test.
We know EIBAID is not DFHPF3 ... because you required an ENTER key to get to this point in program A. Fail the IF test.
The only thing left to do is PERFORM B0006-RETURN-PARA.
Warning: you've got multiple COMMAREA lengths, yet you only check EIBCALEN against 0. You're begging for problems -- if you have 2 lengths, check for each or I predict protection exceptions in your future. |
|
Back to top |
|
|
Vishu
New User
Joined: 23 Mar 2009 Posts: 22 Location: Bangalore
|
|
|
|
For the second program the transfer of DFHCOMMAREA can be done as:
Code: |
IF EIBCALEN = LENGTH (if you know the length of the data you are passing through the PROG1)
move DFHCOMMAREA to WS-COMMAREA
END-IF. |
like for my code I knew the length of data has to be 10 otherwise it will be of no use. So, ill verify whether it is equal to 10 and if not there is no use of passing on the value to the next program.
Code: |
IF EIBCALEN = 10
MOVE DFHCOMMAREA TO WS-COMMAREA
END-IF. |
or if you do not know what the length of the data is going to be, you can use it as
|
|
Back to top |
|
|
Raghu navaikulam
Active User
Joined: 27 Sep 2008 Posts: 193 Location: chennai
|
|
|
|
Hi hernikiten
Quote: |
I have two programs A (transid JI51) and B(transid JI52). A is calling B through LINK |
The basic mistake in your program is
1. The "Linked program " can not run with its own TRANSID. It will work under the "Main Program's TRANSID".
2. The "Linked program" can issue a simple RETURN statement only.
eg. EXEC CICS RETURN END-EXEC.
No TRANSID or COMMAREA are permitted. Even though there are such statements in your program, CICS will simply ignore it and passes control to the main program. So the Linked program can not work in pseudoconversational mode. To work in pseudoconversational mode you have to use XCTL or RETURN statement to invoke another program.
As Robert Sample pointed out, You're begging for problems .
Apart from Robert Sample pointed out, the errors you have committed
You are ignoring MAPFAIL condition. You must HANDLE MAPFAIL condition. If you are not handling MAPFAIL, the program will ABEND if a mapfail condition occurs.
Regards
Raghu |
|
Back to top |
|
|
Robert Sample
Global Moderator
Joined: 06 Jun 2008 Posts: 8696 Location: Dubuque, Iowa, USA
|
|
|
|
Raghu: there's a link to manuals at the top of the page. If you read the CICS Language Reference and Programming Guide, you will find that LINK accepts COMMAREA and the COMMAREA can be used to pass data between the calling and called program. The linked program can have its own TRANSID or not -- CICS won't care. Although I haven't tested this, from the Programming Guide if the linked program issues a RETURN with TRANSID, the TRANSID will not be invoked until control has returned to the calling program and then back up the chain to the transaction associated with the terminal. Once that original transaction does a return, the TRANSID takes effect -- but if the COMMAREA has been deleted in the meantime, the TRANSID will be cleared.
Further, from the Programming Guide on the RECEIVE MAP:
Quote: |
MAPFAIL
occurs if the data to be mapped has a length of zero or does not contain a set-buffer-address (SBA) sequence. It applies only to 3270 devices. The receiving data area contains the unmapped input data stream. The amount of unmapped data moved to the user's area is limited to the length specified in the LENGTH option. The input map is not set to nulls.
This condition also arises if a program issues a RECEIVE MAP command to which the terminal operator responds by pressing a CLEAR or PA key, or by pressing ENTER or a PF key without entering data.
Default action: terminate the task abnormally. |
Ignoring the MAPFAIL makes perfect sense in some cases. As long as the program expects zero bytes of data to be returned, there's no need to have a HANDLE CONDITION MAPFAIL. Perhaps there's an if test for the CLEAR key -- which would definitely work better by ignoring the MAPFAIL. |
|
Back to top |
|
|
aishwarya_20
New User
Joined: 19 Nov 2008 Posts: 57 Location: pune
|
|
|
|
Here in called program how many bytes you are using in LINKAGE SECTION? |
|
Back to top |
|
|
Raghu navaikulam
Active User
Joined: 27 Sep 2008 Posts: 193 Location: chennai
|
|
|
|
Hi Robert
You are right. While LINKing to a program we can use COMMAREA. The data will be received in the LINKAGE SECTION of the "Linked" program. While control is passing to the "Linker", a RETURN statement is enough to pass the data to the "Linker".No need of a COMMAREA. Whatever data available in the LINKAGE SECTION of the "Linked" program can be passed to the "Linker" provided, the length of the data is matching.
The Linked program can also have a TRANSID. This can be used in other way also. The Linked program can be invoked separately with TRANSID. So there must be some condition checking in the beginning of the program to use the program as independent program as well as sub-program. Suppose the a program is defined as a sub-program which is working under another program, then that program need not have a TRANSID.
As per the requirement I did not went deep into the details.
Regarding MAPFAIL, I considered only PROGA. Because in PRGOB there is no receive map statement. As per the program PROGB, the ELSE part alone will be executed.
Quote: |
ELSE
IF EIBAID = DFHPF3
PERFORM B0004-EXIT-PARA
ELSE
PERFORM B0006-RETURN-PARA
END-IF
END-IF. |
Within that ELSE and END-IF there is no receive map statement.
And I considered this program is written by a CICS beginner because of the program structure. So more description is not given.
If the CLEAR KEY is pressed, no matter what ever statements coded in the program, the screen will be erased, otherwise send the map again. No data will be transmitted to the program. If a receive statement is executed, then a MAPFAIL condition will raise. To avoid this situation, HANDLE AID can be used in the beginning of the program.
The real problem here is, the PROGA calls PROGB and immediately after linking PROGB, control is gained by PROGA. This is because of the program structure. The only statement executed in PROGB is
PERFORM B0006-RETURN-PARA and the statements in that paragraph .
That will pass control to PROGA.
Correct me if I am wrong!
Thanks Robert
Regards
Raghu |
|
Back to top |
|
|
|