MainframeCICSCICS Complete Reference

CICS COMMAREA: Complete Guide to Inter-Program Communication and State Management

TT
TopicTrick Team
CICS COMMAREA: Complete Guide to Inter-Program Communication and State Management

Introduction: The COMMAREA as CICS's State-Passing Mechanism

Every software application needs to maintain state between operations. In a web application, state lives in session objects, cookies, or tokens. In a batch COBOL program, state lives in working storage that persists for the program's entire run. In a CICS pseudo-conversational program, neither of those options is available — the task ends after every user interaction. The mechanism CICS provides to preserve state is the COMMAREA.

The COMMAREA (Communication Area) serves two distinct purposes in CICS: it is the channel through which data is passed between programs using EXEC CICS LINK and EXEC CICS XCTL, and it is the state repository that persists data from one pseudo-conversational task invocation to the next via EXEC CICS RETURN. Understanding how to design, size, and safely access the COMMAREA is a core skill for every CICS COBOL developer.


COMMAREA in the LINKAGE SECTION

In COBOL, the COMMAREA is declared as item 01 DFHCOMMAREA in the LINKAGE SECTION. This is a standard CICS convention — the name must be exactly DFHCOMMAREA for the CICS translator to recognise it.

cobol
IDENTIFICATION DIVISION.
PROGRAM-ID. EMPINQ.

DATA DIVISION.
WORKING-STORAGE SECTION.
01  WS-COMMAREA.
    05  WS-CA-EMP-KEY    PIC X(6).
    05  WS-CA-SCREEN-ID  PIC X(4).
    05  WS-CA-FUNC-CODE  PIC X(1).
        88  WS-CA-BROWSE         VALUE 'B'.
        88  WS-CA-DISPLAY        VALUE 'D'.
        88  WS-CA-UPDATE         VALUE 'U'.
    05  WS-CA-MSG-AREA   PIC X(60).

LINKAGE SECTION.
01  DFHCOMMAREA.
    05  LK-CA-EMP-KEY    PIC X(6).
    05  LK-CA-SCREEN-ID  PIC X(4).
    05  LK-CA-FUNC-CODE  PIC X(1).
    05  LK-CA-MSG-AREA   PIC X(60).

The LINKAGE SECTION definition of DFHCOMMAREA must exactly match the structure that the calling program is sending. If the structures do not match in layout, data will be misread — a common source of subtle bugs in CICS programs that communicate with multiple other programs.


The Critical First Step: Testing EIBCALEN

Before accessing DFHCOMMAREA, always test EIBCALEN (the length field in the Execute Interface Block). EIBCALEN tells you how many bytes were passed in the COMMAREA for this invocation:

cobol
PROCEDURE DIVISION.
*── Safe COMMAREA access pattern ─────────────────────────────────
    EVALUATE TRUE
        WHEN EIBCALEN = ZERO
            *> First entry: no COMMAREA passed, initialise
            INITIALIZE WS-COMMAREA
            PERFORM FIRST-TIME-SETUP
        WHEN EIBCALEN < LENGTH OF DFHCOMMAREA
            *> COMMAREA smaller than expected — version mismatch?
            MOVE DFHCOMMAREA TO WS-COMMAREA(1:EIBCALEN)
            PERFORM HANDLE-VERSION-MISMATCH
        WHEN OTHER
            *> Normal re-entry: copy COMMAREA to working storage
            MOVE DFHCOMMAREA TO WS-COMMAREA
            PERFORM PROCESS-USER-INPUT
    END-EVALUATE.

The rule: never access DFHCOMMAREA fields directly when EIBCALEN is zero. And never work directly from LINKAGE SECTION fields in production code — always copy DFHCOMMAREA to a WORKING-STORAGE mirror (like WS-COMMAREA above) before manipulating the data. LINKAGE SECTION storage is owned by CICS; working directly in it is unsafe.


Pseudo-Conversational State Preservation with RETURN COMMAREA

The most important use of the COMMAREA in CICS is preserving transaction state between pseudo-conversational task invocations. After each user interaction, the program issues EXEC CICS RETURN with both TRANSID and COMMAREA options:

cobol
*── After processing, save state and return control to CICS ─────
MOVE WS-COMMAREA TO DFHCOMMAREA

EXEC CICS RETURN
          TRANSID(EIBTRNID)
          COMMAREA(WS-COMMAREA)
          LENGTH(LENGTH OF WS-COMMAREA)
          RESP(WS-RESP)
END-EXEC.

When the user presses an AID key (Enter, PF3, etc.), CICS starts a new task with the same TRANSID and passes the saved COMMAREA to the new task invocation. EIBCALEN will equal the length you specified on the previous RETURN, and DFHCOMMAREA will contain the data you saved.

This is the complete pseudo-conversational COMMAREA lifecycle:

text
Task 1: EIBCALEN=0  → initialise WS-COMMAREA → send initial map
                   → EXEC CICS RETURN TRANSID('EMPI') COMMAREA(WS-COMMAREA)
                                                      ↓ CICS saves COMMAREA
User presses Enter ────────────────────────────────────↓
Task 2: EIBCALEN=71 → MOVE DFHCOMMAREA TO WS-COMMAREA → process input
                   → EXEC CICS RETURN TRANSID('EMPI') COMMAREA(WS-COMMAREA)
                                                      ↓ CICS saves updated COMMAREA
User presses PF3 ──────────────────────────────────────↓
Task 3: EIBCALEN=71 → MOVE DFHCOMMAREA TO WS-COMMAREA → EXEC CICS RETURN (no COMMAREA)

Designing a Good COMMAREA Structure

A well-designed COMMAREA is compact, version-aware, and clearly named. Here is a production-quality COMMAREA design:

cobol
*── WS-COMMAREA: State for the EMPLOYEE INQUIRY transaction ─────
01  WS-COMMAREA.
    *> Version control
    05  WS-CA-VERSION     PIC 9(2)   VALUE 01.

    *> Navigation state
    05  WS-CA-CURRENT-MAP PIC X(8)   VALUE 'EMPLIST '.
    05  WS-CA-FUNC-CODE   PIC X(1)   VALUE SPACES.
        88  WS-CA-LIST              VALUE 'L'.
        88  WS-CA-DETAIL            VALUE 'D'.
        88  WS-CA-UPDATE            VALUE 'U'.
        88  WS-CA-DELETE            VALUE 'X'.

    *> Current record key
    05  WS-CA-EMP-KEY     PIC X(6)   VALUE SPACES.

    *> Browse state
    05  WS-CA-BROWSE-KEY  PIC X(6)   VALUE SPACES.
    05  WS-CA-BROWSE-DIR  PIC X(1)   VALUE 'F'.
        88  WS-CA-FORWARD           VALUE 'F'.
        88  WS-CA-BACKWARD          VALUE 'B'.

    *> User message to display on next send
    05  WS-CA-MSG         PIC X(60)  VALUE SPACES.

    *> Padding to fixed length
    05  FILLER            PIC X(2)   VALUE SPACES.

Best practices for COMMAREA design:

Keep it small. The COMMAREA is stored in the CICS DSA (Dynamic Storage Area) for the duration of the transaction. Large COMMAREs increase storage pressure. If you need more than a few hundred bytes, store the bulk data in a Temporary Storage queue and keep only the TS queue name in the COMMAREA.

Include a version number. When two programs share a COMMAREA and one is updated to change the structure, a version byte lets the receiver detect the mismatch gracefully.

Use fixed-length layouts. The COMMAREA is a contiguous block of bytes. Variable-length layouts cause misalignment bugs. Every program that reads or writes the COMMAREA must use the same COPYLIB definition.

Put a shared COMMAREA definition in a COPYLIB. When multiple programs share a COMMAREA structure, define it in a single copybook and COPY it into each program. This eliminates the risk of definition drift.

cobol
*── Shared copybook: EMPICOMM ───────────────────────────────────
01  WS-COMMAREA.
    05  WS-CA-VERSION    PIC 9(2).
    05  WS-CA-EMP-KEY    PIC X(6).
    05  WS-CA-FUNC-CODE  PIC X(1).
    05  WS-CA-MSG        PIC X(60).
    05  FILLER           PIC X(2).
*── Total: 71 bytes ─────────────────────────────────────────────

COMMAREA in EXEC CICS LINK (Calling a Subprogram)

EXEC CICS LINK invokes another CICS program synchronously — control returns to the calling program when the called program finishes. Data is passed via the COMMAREA option:

cobol
*── Calling program (EMPINQ) ─────────────────────────────────────
01  WS-LINK-COMMAREA.
    05  WS-LINK-EMP-KEY   PIC X(6).
    05  WS-LINK-EMP-NAME  PIC X(30).
    05  WS-LINK-EMP-SAL   PIC S9(7)V99 COMP-3.
    05  WS-LINK-RESP-CODE PIC X(1).

PROCEDURE DIVISION.
    MOVE WS-EMP-KEY TO WS-LINK-EMP-KEY
    INITIALIZE WS-LINK-EMP-NAME WS-LINK-EMP-SAL

    EXEC CICS LINK PROGRAM('EMPGET')
                   COMMAREA(WS-LINK-COMMAREA)
                   LENGTH(LENGTH OF WS-LINK-COMMAREA)
                   RESP(WS-RESP)
    END-EXEC

    IF WS-RESP NOT = DFHRESP(NORMAL)
        PERFORM HANDLE-LINK-ERROR
    END-IF

    *> Called program has populated the COMMAREA
    MOVE WS-LINK-EMP-NAME TO EMPNAMEO
    MOVE WS-LINK-EMP-SAL  TO EMPSALO.
cobol
*── Called program (EMPGET) ─────────────────────────────────────
LINKAGE SECTION.
01  DFHCOMMAREA.
    05  LK-EMP-KEY    PIC X(6).
    05  LK-EMP-NAME   PIC X(30).
    05  LK-EMP-SAL    PIC S9(7)V99 COMP-3.
    05  LK-RESP-CODE  PIC X(1).

PROCEDURE DIVISION.
    EXEC CICS READ FILE('EMPFILE')
              RIDFLD(LK-EMP-KEY)
              INTO(WS-EMP-REC)
              RESP(WS-RESP)
    END-EXEC

    EVALUATE WS-RESP
        WHEN DFHRESP(NORMAL)
            MOVE WS-EMP-NAME TO LK-EMP-NAME
            MOVE WS-EMP-SAL  TO LK-EMP-SAL
            MOVE 'N'         TO LK-RESP-CODE
        WHEN DFHRESP(NOTFND)
            MOVE 'E'         TO LK-RESP-CODE
        WHEN OTHER
            MOVE 'F'         TO LK-RESP-CODE
    END-EVALUATE

    EXEC CICS RETURN END-EXEC.

The COMMAREA is two-way: the calling program passes data IN, and the called program writes results back to the same COMMAREA before returning. After EXEC CICS LINK completes, the calling program reads the updated COMMAREA.


COMMAREA in EXEC CICS XCTL (Transfer Control)

EXEC CICS XCTL transfers control to another program without returning. The original program is terminated. The COMMAREA is passed one-way:

cobol
*── Transfer to EMPMENU without returning ────────────────────────
EXEC CICS XCTL PROGRAM('EMPMENU')
               COMMAREA(WS-MENU-COMMAREA)
               LENGTH(LENGTH OF WS-MENU-COMMAREA)
               RESP(WS-RESP)
END-EXEC.
*> Code below here is never reached after XCTL

Use XCTL when implementing a menu-driven application where pressing PF3 should switch to the main menu program and release the resources of the current program.


When the COMMAREA Is Not Enough: Temporary Storage Alternative

If your transaction state requires more than 32 KB, or if you need to share state between multiple different transactions (not just between invocations of the same transaction), use a Temporary Storage queue:

cobol
*── Build a unique queue name using tran-id + term-id ───────────
MOVE SPACES TO WS-TS-QUEUE
STRING EIBTRNID DELIMITED SIZE
       EIBTRMID DELIMITED SIZE
       INTO WS-TS-QUEUE

*── Save large state to TS queue ─────────────────────────────────
EXEC CICS WRITEQ TS
          QUEUE(WS-TS-QUEUE)
          FROM(WS-LARGE-STATE)
          LENGTH(LENGTH OF WS-LARGE-STATE)
          REWRITE                           *> overwrite item 1
          ITEM(WS-TS-ITEM-NUM)
          RESP(WS-RESP)
END-EXEC

*── Store only the queue name in the COMMAREA ────────────────────
MOVE WS-TS-QUEUE TO WS-CA-TS-QUEUE-NAME
EXEC CICS RETURN TRANSID(EIBTRNID)
                 COMMAREA(WS-COMMAREA)
                 LENGTH(LENGTH OF WS-COMMAREA)
END-EXEC.

Key Takeaways

The COMMAREA is the cornerstone of CICS inter-program communication and pseudo-conversational state management. In pseudo-conversational design, passing a well-structured COMMAREA on every EXEC CICS RETURN is what makes stateless task invocations appear stateful to the user. For program-to-program calls, LINK uses the COMMAREA as a two-way parameter block while XCTL uses it one-way. Always test EIBCALEN before accessing DFHCOMMAREA, always copy DFHCOMMAREA to WORKING-STORAGE before using it, and always define shared COMMAREA structures in a COPYLIB to prevent layout drift.

To see how the COMMAREA fits into the full pseudo-conversational design pattern, continue with CICS Pseudo-Conversational Design. For the complete course, visit the CICS Mastery Course.