CICS program control is how execution moves between programs within a task: LINK calls another program and expects control to return, XCTL transfers control to another program and does not return, and RETURN sends control back to the caller or to CICS. Programs are arranged in logical levels; LINK goes down a level, RETURN goes up a level, and XCTL replaces the current program at the same level. You pass data between programs using COMMAREA (and optionally other mechanisms). Choosing LINK vs XCTL vs RETURN determines whether the caller resumes and how the call stack looks.
Imagine you are reading a book (program A). You say "go to the recipe section" (LINK to program B). You put a bookmark in your book and go read the recipe. When the recipe says "done, go back" (RETURN), you return to your book at the bookmark. That is LINK and RETURN. Sometimes instead you close the book and open a new one (XCTL): you never come back to the first book. Program control is the set of rules for when you go to another program, when you come back, and when you switch to a new program and never come back.
| Command | Meaning |
|---|---|
| LINK | Call another program; control returns when that program does RETURN. Caller waits. Level goes down. |
| XCTL | Transfer control to another program; control does not return. Current program is replaced. Same level. |
| RETURN | Return to the next higher level (caller or CICS). Task can end if returning to CICS. |
LINK transfers control to another program (by program name or channel). The calling program is suspended; it does not run again until the linked-to program issues RETURN. So LINK is like a subroutine call: you go to the other program, it does its work, and when it RETURNs, you continue. You typically pass input (and optionally get output) via COMMAREA. Syntax (conceptually): EXEC CICS LINK PROGRAM(name) COMMAREA(data) LENGTH(len) [RESP(...)]. The linked program receives the COMMAREA and can modify it; when it RETURNs, the caller sees the updated area. Use LINK when you need the current program to resume after the other program finishes (e.g. call a shared validation routine, then continue).
1234567891011*> In program A: call B and get result EXEC CICS LINK PROGRAM('PROGB') COMMAREA(WS-COMMAREA) LENGTH(WS-LEN) RESP(WS-RESP) END-EXEC. *> Control returns here when B does RETURN IF WS-RESP = DFHRESP(NORMAL) *> Use WS-COMMAREA as updated by B ...
XCTL (transfer control) sends control to another program and the current program is replaced. Control does not return to the program that issued XCTL. The new program runs at the same logical level as the one that issued XCTL (it replaces it on the stack). So XCTL is used when the current program is finished and the next program (e.g. next screen handler, next phase) should take over. It also frees the storage of the issuing program. Syntax (conceptually): EXEC CICS XCTL PROGRAM(name) COMMAREA(data) LENGTH(len) [RESP(...)]. Use XCTL for menu-to-program handoff, or when one program has done its job and another continues the transaction without ever returning.
1234567*> In menu program: user chose option 2; run PROG2 EXEC CICS XCTL PROGRAM('PROG2') COMMAREA(WS-COMMAREA) LENGTH(WS-LEN) END-EXEC. *> Control does NOT return here; PROG2 runs and may LINK/ XCTL/ RETURN
RETURN returns control to the next higher logical level. If your program was entered via LINK, RETURN goes back to the program that issued the LINK. If your program is at level 1 (the top transaction program), RETURN returns control to CICS and the task ends (unless you use TRANSID to start another transaction). You can pass COMMAREA and other options on RETURN so the caller receives data. Syntax (conceptually): EXEC CICS RETURN [COMMAREA(data)] [LENGTH(len)] [TRANSID(...)] [RESP(...)]. Every CICS program that is not the final program in a chain must eventually LINK, XCTL, or RETURN; otherwise the task would not progress or end.
12345*> In program B (was LINKed to): finish and return to caller EXEC CICS RETURN COMMAREA(WS-COMMAREA) LENGTH(WS-LEN) END-EXEC.
CICS maintains a logical level for each program in the call stack. Level 0 is CICS. The first program run for the transaction (the one associated with the transaction ID) runs at level 1. When that program does LINK, the linked program runs at level 2; if that program does LINK again, the next runs at level 3, and so on. When a program does RETURN, control goes to the program at the next higher level (level decreases by one). XCTL does not add a level: the program that receives control via XCTL runs at the same level as the program that issued XCTL (the issuer is removed from the stack). So the level reflects the depth of LINK calls; XCTL keeps the same depth.
COMMAREA is the usual way to pass data between programs. On LINK or XCTL you specify COMMAREA(data-area) and LENGTH(length). The receiving program gets the same storage (by reference)—so it can read and update it. When the receiving program does RETURN with COMMAREA and LENGTH, the caller (if any) sees the updated area. All programs that share COMMAREA must agree on its length and layout (e.g. a copybook). You can also pass data via channels and containers instead of COMMAREA in CICS environments that support them.
Use LINK when the current program must continue after the other program finishes: for example, call a shared subroutine (validation, formatting) and then proceed with the result. Use XCTL when the current program is done and the next program takes over for good: for example, a menu program that transfers to the program that handles the selected function, or a program that has completed one phase and hands off to the next phase. LINK increases the call stack and uses more storage until RETURN; XCTL frees the current program and keeps the level flat. Use RETURN when your program has finished its work and control should go back to the caller or to CICS.
1. When Program A does LINK to Program B, and B does RETURN, control goes:
2. XCTL is used when:
3. The first program run for a CICS transaction runs at logical level: