CICS Program Control

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.

Explain Like I'm Five: What Is Program Control?

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.

LINK, XCTL, and RETURN at a Glance

Program control commands
CommandMeaning
LINKCall another program; control returns when that program does RETURN. Caller waits. Level goes down.
XCTLTransfer control to another program; control does not return. Current program is replaced. Same level.
RETURNReturn to the next higher level (caller or CICS). Task can end if returning to CICS.

LINK: Call and Return

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).

cobol
1
2
3
4
5
6
7
8
9
10
11
*> 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 (No Return)

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.

cobol
1
2
3
4
5
6
7
*> 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: Return to Caller or CICS

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.

cobol
1
2
3
4
5
*> In program B (was LINKed to): finish and return to caller EXEC CICS RETURN COMMAREA(WS-COMMAREA) LENGTH(WS-LEN) END-EXEC.

Logical Levels

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.

Passing Data: COMMAREA

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.

When to Use LINK vs XCTL

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.

Step-by-Step: Calling a Subprogram with LINK

  1. Prepare the COMMAREA (or channel/containers) with input for the subprogram. Set the length.
  2. Issue EXEC CICS LINK PROGRAM(program-name) COMMAREA(...) LENGTH(...) RESP(...).
  3. Check RESP. If normal, the linked program ran and returned; the COMMAREA may have been updated. If not normal, handle the error (e.g. program not found, resource failure).
  4. Use the returned data (COMMAREA) and continue. Do not assume control returns only on success—check RESP and handle exceptions.

Best Practices

  • Use LINK only when you need to return; use XCTL when the current program is finished and another takes over.
  • Always check RESP after LINK and XCTL; handle NOTFND, other errors, and avoid assuming COMMAREA was updated if the call failed.
  • Agree on COMMAREA layout and length between caller and callee (e.g. copybook) to avoid overwrites or truncation.
  • Do not nest LINK too deeply without need; each level uses storage and complicates backout/recovery.
  • Use RETURN with COMMAREA when the caller needs output; ensure length and layout match what the caller expects.

Test Your Knowledge

Test Your Knowledge

1. When Program A does LINK to Program B, and B does RETURN, control goes:

  • To CICS
  • Back to Program A
  • To Program B again
  • Nowhere

2. XCTL is used when:

  • You need to return to the caller
  • You are done and another program should take over without returning
  • You want to add a level
  • You want to end the task

3. The first program run for a CICS transaction runs at logical level:

  • 0
  • 1
  • 2
  • LINK