CICS XCTL (Transfer Control) is a program control command that transfers control from one application program to another at the same logical level. Unlike LINK, XCTL does not expect control to return to the calling program - the calling program is terminated and released from memory, making XCTL more memory-efficient.
XCTL stands for "Transfer Control" and is used to permanently transfer program execution to another program. When you execute XCTL, the current program stops executing, and control is transferred to the specified program. The calling program is terminated, so control will never return to it.
This makes XCTL ideal for menu-driven applications where a menu program needs to transfer control to different processing programs based on user selection. Once the user selects an option, control is permanently transferred to that program.
12345678EXEC CICS XCTL PROGRAM('program-name') [COMMAREA(data-area)] [LENGTH(data-length)] [CHANNEL(channel-name)] [RESP(response-code)] [RESP2(response-code-2)] END-EXEC.
Specifies the name of the program to which control is transferred. This program name must be defined in the Program Processing Table (PPT) in your CICS region. The program name is specified as a character string in quotes.
Specifies the data area to be passed to the invoked program. Since the calling program is terminated, only a copy of the COMMAREA is passed, not the original. The called program receives its own copy of the data.
Specifies the length of the data area being passed in the COMMAREA. This tells CICS how many bytes to copy to the called program.
Modern alternative to COMMAREA for passing data. Channels provide more flexible data structures and can handle larger amounts of data. Use CHANNEL instead of COMMAREA in modern CICS applications.
Response codes that indicate the success or failure of the XCTL operation. Always check these codes to handle errors appropriately.
Understanding when to use XCTL versus LINK is crucial for effective CICS programming:
| Aspect | XCTL | LINK |
|---|---|---|
| Control Return | Does not return - calling program terminated | Returns after called program completes |
| Logical Level | Same logical level | Lower logical level |
| Memory Usage | More efficient - releases calling program | Less efficient - keeps calling program in memory |
| COMMAREA | Copy of data passed | Shared data area |
| Use Case | Menu navigation, permanent transfer | Subroutine calls, temporary processing |
This example shows a menu program that transfers control to different programs based on user selection:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667IDENTIFICATION DIVISION. PROGRAM-ID. MENUPROG. ENVIRONMENT DIVISION. DATA DIVISION. WORKING-STORAGE SECTION. 01 WS-COMMAREA. 05 WS-FUNCTION PIC X(1). 88 INQUIRY VALUE 'I'. 88 UPDATE VALUE 'U'. 88 DELETE VALUE 'D'. 01 WS-RESPONSE PIC S9(8) COMP. 01 WS-RESPONSE2 PIC S9(8) COMP. LINKAGE SECTION. 01 DFHCOMMAREA. 05 COMM-FUNCTION PIC X(1). PROCEDURE DIVISION. * Get function selection from user or previous program IF EIBCALEN > 0 MOVE COMM-FUNCTION TO WS-FUNCTION END-IF * Transfer control based on function EVALUATE TRUE WHEN INQUIRY EXEC CICS XCTL PROGRAM('CUSTINQ') COMMAREA(WS-COMMAREA) LENGTH(LENGTH OF WS-COMMAREA) RESP(WS-RESPONSE) RESP2(WS-RESPONSE2) END-EXEC WHEN UPDATE EXEC CICS XCTL PROGRAM('CUSTUPD') COMMAREA(WS-COMMAREA) LENGTH(LENGTH OF WS-COMMAREA) RESP(WS-RESPONSE) RESP2(WS-RESPONSE2) END-EXEC WHEN DELETE EXEC CICS XCTL PROGRAM('CUSTDEL') COMMAREA(WS-COMMAREA) LENGTH(LENGTH OF WS-COMMAREA) RESP(WS-RESPONSE) RESP2(WS-RESPONSE2) END-EXEC WHEN OTHER * Invalid function - return to menu EXEC CICS RETURN TRANSID('MENU') END-EXEC END-EVALUATE. * Check for errors (though control won't return here if XCTL succeeds) IF WS-RESPONSE NOT EQUAL DFHRESP(NORMAL) EXEC CICS WRITE OPERATOR TEXT('XCTL command failed') END-EXEC EXEC CICS RETURN TRANSID('MENU') END-EXEC END-IF.
This example demonstrates proper error handling when using XCTL:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950WORKING-STORAGE SECTION. 01 WS-RESPONSE PIC S9(8) COMP. 01 WS-RESPONSE2 PIC S9(8) COMP. 01 WS-PROGRAM-NAME PIC X(8). 01 WS-COMMAREA PIC X(100). PROCEDURE DIVISION. * Determine which program to transfer to PERFORM DETERMINE-TARGET-PROGRAM * Attempt to transfer control EXEC CICS XCTL PROGRAM(WS-PROGRAM-NAME) COMMAREA(WS-COMMAREA) LENGTH(LENGTH OF WS-COMMAREA) RESP(WS-RESPONSE) RESP2(WS-RESPONSE2) END-EXEC. * Handle errors (this code executes only if XCTL fails) IF WS-RESPONSE NOT EQUAL DFHRESP(NORMAL) PERFORM HANDLE-XCTL-ERROR EXEC CICS RETURN TRANSID('MENU') END-EXEC END-IF. * If we reach here, XCTL failed * (Successful XCTL never returns) GOBACK. HANDLE-XCTL-ERROR. EVALUATE WS-RESPONSE WHEN DFHRESP(PGMIDERR) EXEC CICS SEND FROM('ERROR: Program not found') END-EXEC WHEN DFHRESP(NOTAUTH) EXEC CICS SEND FROM('ERROR: Not authorized to execute program') END-EXEC WHEN DFHRESP(LENGERR) EXEC CICS SEND FROM('ERROR: Invalid COMMAREA length') END-EXEC WHEN OTHER EXEC CICS SEND FROM('ERROR: XCTL failed') END-EXEC END-EVALUATE.
Modern CICS applications can use channels instead of COMMAREA for more flexible data passing:
123456789101112131415161718192021222324WORKING-STORAGE SECTION. 01 WS-RESPONSE PIC S9(8) COMP. 01 WS-CHANNEL-NAME PIC X(16) VALUE 'MAIN-CHANNEL'. PROCEDURE DIVISION. * Put data into channel before XCTL EXEC CICS PUT CONTAINER('CUSTOMER-DATA') CHANNEL(WS-CHANNEL-NAME) FROM(WS-CUSTOMER-RECORD) FLENGTH(LENGTH OF WS-CUSTOMER-RECORD) END-EXEC * Transfer control using channel EXEC CICS XCTL PROGRAM('CUSTPROC') CHANNEL(WS-CHANNEL-NAME) RESP(WS-RESPONSE) END-EXEC. * Handle errors IF WS-RESPONSE NOT EQUAL DFHRESP(NORMAL) PERFORM HANDLE-ERROR EXEC CICS RETURN END-EXEC END-IF.
| Response Code | Numeric Value | Meaning |
|---|---|---|
| NORMAL | 0 | XCTL completed successfully - control transferred to target program |
| Response Code | Numeric Value | Meaning |
|---|---|---|
| PGMIDERR | 8 | Program not found - the specified program does not exist in the PPT |
| NOTAUTH | 10 | Not authorized - user does not have permission to execute the target program |
| LENGERR | 22 | Length error - COMMAREA length is invalid or exceeds maximum allowed |
| INVREQ | 16 | Invalid request - XCTL parameters are incorrect or incompatible |
| PGMERR | 12 | Program error - the target program encountered an error during execution |
Always check the RESP parameter after XCTL to handle errors. While successful XCTL never returns control, failed XCTL will return control, and you need to handle the error appropriately.
XCTL is ideal for menu-driven applications where you permanently transfer control based on user selection. The menu program acts as a router, transferring control to the appropriate processing program.
Use COMMAREA for simple data structures and backward compatibility. Use CHANNEL for modern applications that need more flexible data structures or larger amounts of data.
When XCTL executes, the calling program's working storage and procedure division are released, but I/O areas, GETMAIN areas, and chained Linkage Section areas remain intact.
Imagine you're playing a game and passing the controller:
When you're done playing your part of the game, you hand the controller to your friend and they start playing their part. You don't get the controller back - they keep playing until they're done, and then they might hand it to someone else or finish the game.
CICS XCTL is like handing the controller to your friend. Your program (you) hands control to another program (your friend), and you don't get it back. The other program takes over completely and continues running until it's done.
This is different from LINK, which is like asking your friend to help you with something, and then they give the controller back to you when they're done helping.
Write a CICS XCTL command that transfers control to a program named 'CUSTINQ' and passes a COMMAREA named WS-COMMAREA with a length of 100 bytes.
12345EXEC CICS XCTL PROGRAM('CUSTINQ') COMMAREA(WS-COMMAREA) LENGTH(100) END-EXEC.
Write a CICS XCTL command with error handling that checks for program not found errors and displays an appropriate message.
12345678910111213141516171819WORKING-STORAGE SECTION. 01 WS-RESPONSE PIC S9(8) COMP. PROCEDURE DIVISION. EXEC CICS XCTL PROGRAM('TARGET-PROG') COMMAREA(WS-COMMAREA) LENGTH(LENGTH OF WS-COMMAREA) RESP(WS-RESPONSE) END-EXEC. IF WS-RESPONSE NOT EQUAL DFHRESP(NORMAL) IF WS-RESPONSE = DFHRESP(PGMIDERR) EXEC CICS SEND FROM('ERROR: Program not found') END-EXEC END-IF EXEC CICS RETURN END-EXEC END-IF.
Create a menu program that uses XCTL to transfer control to different programs based on a function code stored in WS-FUNCTION ('I' for inquiry, 'U' for update, 'D' for delete).
12345678910111213141516171819202122232425262728293031323334353637383940414243WORKING-STORAGE SECTION. 01 WS-FUNCTION PIC X(1). 88 INQUIRY VALUE 'I'. 88 UPDATE VALUE 'U'. 88 DELETE VALUE 'D'. 01 WS-COMMAREA PIC X(100). 01 WS-RESPONSE PIC S9(8) COMP. PROCEDURE DIVISION. * Get function code from user input * ... (code to get WS-FUNCTION) ... * Transfer control based on function EVALUATE TRUE WHEN INQUIRY EXEC CICS XCTL PROGRAM('CUSTINQ') COMMAREA(WS-COMMAREA) LENGTH(LENGTH OF WS-COMMAREA) RESP(WS-RESPONSE) END-EXEC WHEN UPDATE EXEC CICS XCTL PROGRAM('CUSTUPD') COMMAREA(WS-COMMAREA) LENGTH(LENGTH OF WS-COMMAREA) RESP(WS-RESPONSE) END-EXEC WHEN DELETE EXEC CICS XCTL PROGRAM('CUSTDEL') COMMAREA(WS-COMMAREA) LENGTH(LENGTH OF WS-COMMAREA) RESP(WS-RESPONSE) END-EXEC END-EVALUATE. * Handle errors IF WS-RESPONSE NOT EQUAL DFHRESP(NORMAL) EXEC CICS RETURN TRANSID('MENU') END-EXEC END-IF.
1. What is the primary purpose of CICS XCTL?
2. What happens to the calling program when XCTL executes?
3. How is data passed when using XCTL?
4. Which command should you use if you need the calling program to continue after the called program completes?
5. What is a common use case for XCTL?
Learn about CICS LINK command for calling subprograms that return control
Understanding program control and data passing in CICS applications
Learn about passing data between CICS programs using COMMAREA and channels
Understanding how to return control to CICS from a program