Mainframe Environment Primer

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production.

The reference material consulted while preparing these pages is listed in the section bibliography.

This page is written against ISO/IEC 1989:2023 (edition 3, January 2023; a 4th edition is upcoming), IBM Enterprise COBOL for z/OS 6.5 (PTFs through September 2026) running on z/OS 3.2, and GnuCOBOL 3.2, and it was checked on 2026-10-20. It is the one page of the section that is about the platform rather than the language: the other pages explain COBOL statements, and this one explains the machine, the operating system, the files and the tools around the code that a COBOL programmer on IBM Z has to know before the first job runs. Most COBOL in production still runs there, so the vocabulary matters even for a developer who writes and tests everything with GnuCOBOL on a laptop.

Nothing on this page that is specific to z/OS was run: there is no z/OS system in the verification environment, and nobody signed in to IBM Z Xplore or any other mainframe service on the reader’s behalf. The JCL and the ISPF and SDSF descriptions are therefore labelled "z/OS; not run here" and were checked against the IBM documentation listed in the references. Only the EBCDIC collating-sequence example is portable; it was compiled with cobc -x -Wall (GnuCOBOL 3.2.0, also with -std=ibm) and run, and its output is real. Vendor-neutral facts that vary by installation (data-set high-level qualifiers, job classes, procedure library names) are written the way IBM’s own examples write them: as values a site chooses. The running example is Circulation, the library back office of this section, whose data sets are named USERID.CIRC.BOOKMAST, USERID.CIRC.MEMBMAST and USERID.CIRC.LOANTRAN; USERID stands for the programmer’s own user ID.

The structure follows how a developer meets the platform. The Compilers and Dialects page lists the compilers; JCL for COBOL Programmers explains job control in depth; Data Sets and Mainframe Utilities covers allocation and the utility programs; and Modern Tooling: VS Code and Zowe covers the workstation side. This page is the map that connects them.

The system at a glance

A z/OS system: a developer workstation reaches an LPAR on an IBM Z machine through TN3270 and Zowe; inside the LPAR JES2, TSO/E, CICS, Db2, IMS and z/OS UNIX run as address spaces above data sets, VSAM, the catalog and the spool

Figure: a z/OS system as a COBOL developer sees it. The sketch is conceptual and not drawn from any IBM documentation.

Read the figure from the outside in. A mainframe here means an IBM Z machine. The hardware generations are known by name: z13, z14, z15, z16 (2022) and z17 (2025). The compiler is tuned for a generation through the ARCH and TUNE options; Enterprise COBOL 6.5 adds ARCH(15) and TUNE(15) for the z17, removes ARCH(10), and makes ARCH(11) the default, so a program compiled without options runs on a much older machine than the one that hosts it. A single machine is divided into logical partitions (LPARs) by the firmware hypervisor (PR/SM), and each LPAR runs its own copy of an operating system. A shop typically has separate LPARs for development, test and production, so a program moves from one to the next by being rebuilt or by copying its load module, and the same data-set names can exist in each. The operating system for COBOL is z/OS, currently version 3.2 (generally available on 30 September 2025). Other IBM Z operating systems exist (z/VM, z/VSE and Linux on IBM Z), and COBOL runs on some of them, but the rest of this section means z/OS unless it says otherwise.

Inside z/OS, work is organized into address spaces: each started task, each batch job, each TSO user and each CICS or Db2 region has its own virtual storage. JES2 reads jobs and holds their output, TSO/E gives each user an interactive session, CICS runs online transactions, Db2 and IMS are database managers, and z/OS UNIX System Services (USS) provides a UNIX-style file system and shell. All of them reach the disks through the data-set machinery of DFSMS, described below. The Language Environment (LE), covered in Compiling, Linking and Language Environment, is the runtime that a compiled COBOL program calls for storage, messages, condition handling and the CALL interface.

Batch and online work

Mainframe workloads fall into two families, and a COBOL programmer usually writes for both.

Aspect Batch Online (OLTP: online transaction processing)

How work starts

A job is submitted and waits for an initiator; it can run in the evening or on a schedule

A user at a terminal or a service sends a request, and the transaction manager starts a program for it

Typical duration

Minutes to hours, processing millions of records

Milliseconds to a few seconds per request

Data access

Whole files, read sequentially or sorted; VSAM and Db2 in bulk

One record or one row per request, by key

Runtime

Job step in a batch address space under JES2

A CICS or IMS region that stays up and runs many transactions

Unit of failure and restart

The step or the job; restart from a checkpoint or rerun after fixing the data

The transaction, which commits or backs out as a unit

Circulation example

The nightly run that validates LOANTRAN, applies checkouts and returns, assesses fines and prints the report

The CINQ inquiry, in which a librarian looks up a member and the member’s loans

Where it is covered

JCL for COBOL Programmers

CICS Online Programming

Batch is the original style of COBOL: a program reads a file, processes it record by record and writes another file, and that structure is why so much of the language is about files. Online programs trade volume for latency and are written as short, stateless units that a transaction manager runs; they cannot use the OPEN of a sequential file in the same way, and most of the EXEC CICS or EXEC SQL statements they contain are translated before compilation.

Data sets

A data set is the z/OS word for a file. Unlike the byte stream of a UNIX file, a traditional data set has a record format chosen when it is created, and the system keeps it in blocks on a disk volume (DASD). The COBOL FD and the data set must agree on what a record is, so the attributes below appear throughout the section.

Attribute Meaning

DSORG (organization)

PS for a physical sequential data set, PO for a partitioned data set (a library), DA for direct access; VSAM clusters are not described by DSORG

RECFM (record format)

F fixed, FB fixed blocked, V variable, VB variable blocked, U undefined; the FD and the data set agree for a given file

LRECL (logical record length)

The record length in bytes; for variable formats it includes the 4-byte record descriptor word, so the COBOL record is 4 bytes shorter

BLKSIZE (block size)

The size of one physical block; most shops let the system determine it by coding 0, and the system chooses the best size for the device

Space

Tracks, cylinders or blocks, with a primary and a secondary quantity; running out of space ends a job with an abend such as SB37

Circulation’s master files are fixed-length and blocked: USERID.CIRC.BOOKMAST and USERID.CIRC.MEMBMAST have RECFM=FB and LRECL=60, and USERID.CIRC.LOANTRAN has RECFM=FB and LRECL=30, which are the byte counts of the BOOKREC, MEMBREC and LOANREC layouts used across this section.

Kinds of data sets

  • Sequential (PS): records stored one after another and read from the first. Most batch input and output, and all report output, are sequential. A COBOL ORGANIZATION IS SEQUENTIAL file with ACCESS MODE IS SEQUENTIAL maps to this. See Sequential Files.

  • Partitioned (PDS and PDSE): a library with a directory and named members, each of which is like a small sequential file. A source library such as USERID.CIRC.COBOL holds one member per program, a copybook library such as USERID.CIRC.COPYLIB holds BOOKREC, MEMBREC and LOANREC, and a load library such as USERID.CIRC.LOADLIB holds the executable programs. A PDSE (partitioned data set extended) is the modern form: it reuses freed space automatically, has no fixed directory size and can hold program objects. Members are addressed as USERID.CIRC.COPYLIB(BOOKREC), and a member name is at most 8 characters.

  • VSAM (Virtual Storage Access Method): keyed and relative storage managed by the access method rather than by the program. A KSDS (key-sequenced) is the indexed file of COBOL, an ESDS (entry-sequenced) is an append-only sequence, an RRDS (relative record) is a table of numbered slots, and an LDS (linear) is a byte array that Db2 uses. Clusters are created with the IDCAMS utility. See Indexed Files and VSAM and Relative Files.

  • Generation data groups (GDGs): a family of sequential data sets related by one base name, whose members are generations named G0001V00 and so on. Jobs refer to them relatively: (+1) creates the next generation and (0) and (-1) read the current and the previous one. The nightly Circulation run uses a GDG for each day’s transaction file, so that last night’s input can be reread. The JCL is explained in JCL for COBOL Programmers.

  • z/OS UNIX files are not data sets; they live in the hierarchical file system and are described in the USS section below.

Catalogs and names

A catalog maps a data-set name to the volume that holds it and its attributes, so that a program (or a DD statement) can refer to USERID.CIRC.BOOKMAST without saying which disk it is on. There is a master catalog and any number of user catalogs, all of them integrated catalog facility (ICF) catalogs, and an alias in the master catalog points a high-level qualifier at the right user catalog. A data set that is not cataloged can be used only if the volume is named in the job.

The naming rules follow from the way the catalog is searched:

  • A name is made of qualifiers separated by periods, and the whole name, including the periods, is at most 44 characters.

  • Each qualifier is 1 to 8 characters. The first character is a letter or one of the national characters (@, # and $, whose code points depend on the code page); the others may also be digits or a hyphen.

  • The first qualifier, the high-level qualifier (HLQ), is usually the user ID or a project code, and security rules (RACF profiles or an equivalent product) are keyed on it.

  • A member name in parentheses is part of the reference, not of the name, and has its own limit of 8 characters.

Taken together, USERID.CIRC.BOOKMAST is three qualifiers of 6, 4 and 8 characters, 21 characters long with the periods, and the first qualifier is the HLQ. The exact rules, including the extra restrictions on GDG base names and on names of VSAM components, are in the IBM manual DFSMS Using Data Sets.

TSO/E and ISPF

TSO/E (Time Sharing Option extensions) is the interactive session a user gets, and ISPF (Interactive System Productivity Facility) is the full-screen menu system that runs inside it. A developer reaches it with a 3270 terminal emulator that speaks TN3270 to the mainframe, and a function key map (PF3 to leave, PF7 and PF8 to scroll, PF12 to cancel) that depends on the emulator’s configuration. The first screen is a menu of numbered options; the ones below are the ones a COBOL programmer uses all day.

Option What it does

2 Edit

Edit a member or a sequential data set; line commands (I insert, D delete, C and M copy and move, R repeat) in the number area, and primary commands such as FIND, CHANGE ALL, SUBMIT (SUB), COPY and CREATE, at the command line

3.2 Data set utility

Allocate, rename, delete and display information about a data set or a PDS member, so the RECFM, LRECL and space are chosen without writing JCL

3.4 Data set list

List the data sets under a prefix such as USERID.CIRC, and open any of them for browse, edit or other actions

3.3 Move/copy utility

Copy members between libraries

S (SDSF), where installed

Open the system display and search facility, described next

Option numbers and the way SDSF is reached are set by the installation and can differ from this table. ISPF line commands and primary commands in the editor take a few minutes to learn, and a short exercise is to create the USERID.CIRC.COBOL library with option 3.2, create the member LOANUPD in it with option 2, type the program and submit the job that compiles it.

SDSF and the JES2 spool

JES2 (Job Entry Subsystem 2) accepts a submitted job, queues it by its job class, and hands it to an initiator, which is the batch address space that runs the steps one after another. JES2 also keeps everything the job writes to SYSOUT data sets. That storage is the spool, and a job’s listing, messages and report stay on it until somebody purges them. A job gets a job name (the name on the JOB statement) and a job number (JOB followed by digits) that identifies one run.

SDSF (System Display and Search Facility) is the ISPF application that displays the spool and the queues. A COBOL programmer uses a few panels and commands:

Panel or command Use

DA

Display active jobs

ST

Status of jobs in the queue (ST shows jobs in the input, active and output queues)

H

Held output (jobs whose output class is a held class)

PREFIX and OWNER

Limit the list to the job names or owner that you want

S (select) next to a job

Open the job’s output; ? lists the job’s data sets

P (purge) next to a job

Delete the job and its output from the spool when the output is no longer needed

For a compile-and-run job the output is a set of SYSOUT data sets: the job log (JESMSGLG), the JCL listing (JESJCL), the system messages (JESYSMSG), the compiler listing, the link-edit map and what the program displays. The return code of each step (RC=0000 for success, 4 for warnings, 8 for errors, 12 and 16 for severe problems by convention) and the abend code, if any, are the first things to read. An abend such as S0C7 (a data exception: the program used non-numeric data in a numeric field) or S0C4 (a protection exception, usually a wrong address or subscript) is explained, with its fix, in Debugging and Troubleshooting.

z/OS UNIX System Services

z/OS UNIX System Services (USS) is the part of z/OS that provides a POSIX-style hierarchical file system (usually zFS), a shell (reached with the OMVS command in TSO, or with SSH) and a C library interface. For COBOL it matters in four ways.

  • Compilation. cob2 is the command-line front end of the Enterprise COBOL compiler in the shell. PTF PH72005 for Enterprise COBOL 6.5 (July 2026) extended cob2 and z/OS UNIX support; the compiler options are listed in Compiling, Linking and Language Environment.

  • Files. A COBOL program can read and write USS files, and ORGANIZATION IS LINE SEQUENTIAL is supported only for files in the hierarchical file system, never for traditional data sets. A tagged file (chtag) carries its code page, so that tools can convert text between EBCDIC and ASCII-based encodings correctly.

  • Tooling. Zowe and many open-source tools on z/OS run on top of USS; Git for z/OS and the SSH daemon are USS programs.

  • Interoperability. Java and C programs on z/OS run in USS and can call COBOL, and the reverse, as described in Interoperability with C, Java and Python.

Where the book Modern Mainframe Development (Taulli, O’Reilly 2022) reads an ASSIGN TO "Customers.dat" file with LINE SEQUENTIAL next to z/OS JCL, the two ideas must not be mixed: on z/OS a traditional data set is reached through a DD name, and LINE SEQUENTIAL belongs to the USS file system, as in the paragraph above.

EBCDIC and code pages

IBM mainframes store characters as EBCDIC (Extended Binary Coded Decimal Interchange Code), an 8-bit encoding that is older than ASCII and not a superset of it. Every character literal in a COBOL program compiled on z/OS is stored as an EBCDIC byte, and every PIC X field and every text data set holds EBCDIC unless a code page says otherwise. Some code points differ from ASCII in ways that matter:

Character EBCDIC (code page 037) ASCII

space

40

20

0 to 9

F0 to F9

30 to 39

A to I

C1 to C9

41 to 49

J to R

D1 to D9

4A to 52

S to Z

E2 to E9

53 to 5A

a to i

81 to 89

61 to 69

Four consequences follow for a COBOL programmer:

  • Collating order differs. In EBCDIC a space sorts before letters, lowercase letters sort before uppercase letters, and letters sort before digits, so "A1" sorts before "1A" on z/OS but not on an ASCII host. A key that is sorted or compared as characters sorts differently in the two worlds. The alphabet is also not contiguous: there are gaps between I and J, and between R and S, which breaks code that assumes that consecutive letters have consecutive codes.

  • The code page matters. Code page means the exact mapping of the 256 byte values; common ones are 037 (United States and Canada) and 1047 (Latin 1 / Open Systems, which is the usual one for USS). They agree on the letters and digits and differ on a few punctuation characters, notably the square brackets and the caret, so that text can look right in one tool and wrong in the other.

  • Only text is converted. A file moved to a workstation in text mode is converted record by record from EBCDIC to ASCII, and that conversion would destroy a binary field. Packed-decimal (COMP-3) and binary (COMP) fields are bytes, not characters, and must not be translated, so a record layout with numeric fields is transferred in binary mode or its numeric fields are first converted to DISPLAY with a sign. This is one reason a data exchange format such as JSON or XML (see JSON GENERATE and PARSE) is preferred at a system boundary.

  • Signs are zoned. A zoned-decimal (DISPLAY) number carries its sign in the last byte, and the sign nibble differs between EBCDIC and ASCII, so a file of signed fields cannot be read on the other platform without conversion.

The National, UTF-8 and Code Pages page covers the NATIONAL and UTF-8 data types and the CODEPAGE compiler option in full. Here a short example shows the first consequence, the collating order, running on any host.

The same bytes, a different order

GnuCOBOL on a workstation stores PIC X fields as ASCII, and Enterprise COBOL on z/OS stores them as EBCDIC. The two programs below are identical except that the first declares the alphabet EBCDIC and makes it the program collating sequence, so the comparison orders the characters as an EBCDIC machine would, while the stored bytes stay as they are.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. SORTORDER.
       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       OBJECT-COMPUTER. CIRC-HOST
           PROGRAM COLLATING SEQUENCE IS EBCDIC-ORDER.
       SPECIAL-NAMES.
           ALPHABET EBCDIC-ORDER IS EBCDIC.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-CODE-A        PIC X(2) VALUE "A1".
       01  WS-CODE-B        PIC X(2) VALUE "1A".
       PROCEDURE DIVISION.
       MAIN-PARA.
           DISPLAY "Stored bytes: " FUNCTION HEX-OF(WS-CODE-A) " "
               FUNCTION HEX-OF(WS-CODE-B)
           IF WS-CODE-A < WS-CODE-B
               DISPLAY "A1 sorts before 1A"
           ELSE
               DISPLAY "1A sorts before A1"
           END-IF
           STOP RUN.
Stored bytes: 4131 3141
A1 sorts before 1A

The stored bytes 41 31 and 31 41 are the ASCII codes of A1 and 1A, so the data did not change; only the order did, because letters come before digits in EBCDIC. The second program is the same source with the PROGRAM COLLATING SEQUENCE clause removed (its OBJECT-COMPUTER paragraph ends after CIRC-HOST), so it uses the native ASCII order:

Stored bytes: 4131 3141
1A sorts before A1

A pitfall is to name the alphabet in PROGRAM COLLATING SEQUENCE and forget to define it in SPECIAL-NAMES. This is a deliberately wrong version (the ALPHABET entry and the SPECIAL-NAMES header removed) and the real diagnostics of cobc -x -Wall:

badorder.cob:6: error: 'EBCDIC-ORDER' is not defined
    4 |        CONFIGURATION SECTION.
    5 |        OBJECT-COMPUTER. CIRC-HOST
    6 >            PROGRAM COLLATING SEQUENCE IS EBCDIC-ORDER.
    7 |        DATA DIVISION.
    8 |        WORKING-STORAGE SECTION.
badorder.cob:6: error: 'EBCDIC-ORDER' is not an alphabet-name

On z/OS the comparison in the first program needs no clause, because the native collating sequence already is EBCDIC. The rest of this section compiles its examples with GnuCOBOL on ASCII hosts, so output that depends on character order (a sort of alphanumeric keys, for instance) is labelled where the z/OS result would differ.

A developer’s day

This sketch follows one Circulation change, a fix to the loan update program LOANUPD, from edit to the spool. It is a consulted overview: the mainframe workflow is described the way IBM and the Zowe documentation describe it, and it was not run here.

Step Where What happens

1. Edit

ISPF option 2, or VS Code with IBM Z Open Editor and Zowe Explorer

The source member USERID.CIRC.COBOL(LOANUPD) is changed; the copybooks come from USERID.CIRC.COPYLIB

2. Compile and link

A JCL job calling a catalogued procedure

A compile-and-link procedure (for example IGYWCL, the name IBM uses in its examples, though each site names and customises its own) runs the compiler and the linkage editor, and puts the load module in USERID.CIRC.LOADLIB

3. Submit

ISPF SUB, zowe zos-jobs submit, or a VS Code command

JES2 reads the job, assigns a job number and queues it

4. Run

A second job step, or a second job

The program runs in a batch address space with its files allocated by DD statements

5. Read the output

SDSF, or zowe zos-jobs view

The compiler listing and messages, the return code and the program output are in the spool

6. Fix and repeat

The editor

A compile error or a bad return code leads back to step 1

7. Promote

Source control and the shop’s pipeline

Modern shops keep source in Git and promote by a pipeline; older shops use a change-management product

A minimal job for steps 2 to 4 looks like this. The JOB statement names the job and its classes, EXEC IGYWCL runs the compile and link procedure, and its COBOL.SYSLIB and COBOL.SYSIN overrides tell the compiler where the copybooks and the source are (it is SYSLIB that resolves COPY, not a copy step). The second step runs the new load module with the Circulation data sets named by their DD names. Everything here is z/OS; not run here.

//CIRCJOB1 JOB (ACCT),'CIRC UPDATE',CLASS=A,MSGCLASS=H,NOTIFY=&SYSUID
//COMPILE  EXEC IGYWCL
//COBOL.SYSLIB DD DISP=SHR,DSN=USERID.CIRC.COPYLIB
//COBOL.SYSIN  DD DISP=SHR,DSN=USERID.CIRC.COBOL(LOANUPD)
//LKED.SYSLMOD DD DISP=SHR,DSN=USERID.CIRC.LOADLIB(LOANUPD)
//RUN      EXEC PGM=LOANUPD
//STEPLIB  DD DISP=SHR,DSN=USERID.CIRC.LOADLIB
//BOOKMAST DD DISP=SHR,DSN=USERID.CIRC.BOOKMAST
//LOANTRAN DD DISP=SHR,DSN=USERID.CIRC.LOANTRAN
//SYSOUT   DD SYSOUT=*

The job is explained, statement by statement, in JCL for COBOL Programmers. The name IGYWCL, the job class, the MSGCLASS and the procedure library are installation conventions, so a real shop’s version has different values. In the program, the DD name LOANTRAN is reached through SELECT LOAN-TRANSACTIONS ASSIGN TO LOANTRAN, as described in File Concepts, SELECT and FD.

Getting to a mainframe without owning one

A developer who has no employer-provided system has three routes. IBM Z Xplore is IBM’s learning platform, which gives learners access to a hosted z/OS environment through exercises and challenges. The Open Mainframe Project COBOL Programming Course is a free course that teaches COBOL with VS Code and Zowe. And GnuCOBOL 3.2 on a workstation runs everything portable in this section, which is the tool used to verify the examples. The first page of the section, Getting Started with COBOL, gives the installation steps.

Where the book is outdated

Modern Mainframe Development (Tom Taulli, O’Reilly, 1st edition, March 2022) is a survey-level introduction whose chapters 2 and 3 describe the environment on this page. It was consulted as an overview for the topics covered here and nothing is copied from it. Its platform facts were current for its publication date and have since moved:

The book says Current as of 2026-10-20

z/OS 2.4

z/OS 3.2 (generally available 30 September 2025)

The z15 is the newest mainframe

The z16 (2022) and the z17 (2025) are newer; Enterprise COBOL 6.5 adds ARCH(15) and TUNE(15) for the z17

IBM’s free 180-day z/OS access

IBM Z Xplore

Zowe v1 and its prerequisites (an old Node.js and Java 8)

Zowe 3.x

OpenCobolIDE as the PC environment

No longer maintained; use GnuCOBOL 3.2 with VS Code

Micro Focus products and tooling

Now part of Rocket Software (Rocket Visual COBOL, Rocket Enterprise Developer)

Tooling from the book’s sponsor (BMC and Compuware products)

Named only in prose here, alongside IBM, Broadcom and open-source equivalents; the book’s demos are not reproduced

Common mistakes

  • Treating a data set as a byte stream. A record has a length and a format. A program that reads USERID.CIRC.BOOKMAST with a record longer than the data set’s LRECL fails or truncates, and the FD and the data set disagree at run time rather than at compile time.

  • Forgetting that members are not data sets. A PDS member is one name inside a library; allocating a library without a member name and trying to read it as a sequential file gives an error from the system, not from the program.

  • Comparing or sorting text without knowing the platform. A sort key built from letters and digits gives a different order on ASCII and EBCDIC hosts; test with the collating sequence of the production system.

  • Converting a whole file as text. Moving a record with packed or binary fields in text mode corrupts it.

  • Assuming the example job names are universal. Job classes, procedure names, HLQs and ISPF option numbers are set by the installation; use the shop’s standards.

  • Leaving old job output on the spool. Purge it when you are done, because spool space is shared and a full spool stops the whole system.