Hello World on z/OS

Photo credit Insignifica (Flickr)

Yak 00: Data sets are files! (Navigating z/OS)

Let’s say you’re starting like me. You have z/OS installed and the first thing you want to do is a hello world in COBOL or something. You figure there are probably sensible ways of moving the file from your host filesystem into z/OS but the program isn’t very long so to speed things along you’re just going to retype it. That sounds pretty straight forward right? Create a file, retype your program, save file, run compiler, execute program.

  • PROJECT: Ridiculously unintuitive: this must be a userid. In theory the userid of the account you logged into TSO with. If you’re following along using hercules you’re probably using ibmuser to start out.
  • GROUP: Think of this as your folder name. It can be anything you want as long as you stay within data set name limitations. Be mindful of both character length and moving too far beyond alphanumeric inputs.
  • TYPE: What the file actually is. For our COBOL program this will be COBOL. For JCL it will be JCL. But as we move through the compiling, linking and executing phases there will be other less straight forward types z/OS will create for us like LOAD and OBJ
  • MEMBER: In our ‘data sets are files’ analogy this is your file name. Like GROUP it can be pretty much whatever you want it to be with the same limitations. If you keep things straight forward and alphanumeric for the first program, you shouldn’t have to know too much about what z/OS will and will not allow here.

Yak 01: You’re going to use fn A LOT (Working in ISPF)

Working with ISPF is … interesting. I feel like every time a Vim -vs- Emacs argument breaks out over the internet all participants should be required to use ISPF for a period of time just so they appreciate what we have in modern text based editors.

  • F3: Exits out of whatever screen you’re on and moves back to the previous screen. If you are editing a data set this will also automatically save your work before exiting
  • F8: Scroll down
  • F7: Scroll up

Yak 02: Allocating a Data Set for COBOL

If I had to pick the thing that caused the most angst it was figuring out what settings my data set should have in order for my COBOL code to compile correctly.

created COBLOG0 just to snag this screen cap
  • RECORD LENGTH needs to be 80. Remember COBOL originally ran on punch cards that were 80 columns in width, so COBOL programs are fixed width and 80 columns. If you set RECORD LENGTH to something larger than 80 the compiler will tell you “input LRECL too large for language type”. LRECL stands for Logical Record Length and it took me forever to figure out what this had to do with anything. Weirdly, the solution came when I got stuck in a nasty error loop in ISPF’s command line over a rouge hyphen. Quite at random z/OS spat out an message telling me “BTW LRECL for JCL programs needs to be 80” and I made the connection.
  • BLOCK SIZE should be 4000. Well, okay, this one was my own fault. I knew by this point that Block Size needed to be a multiple of LRECL and I just wasn’t pay attention and kept it set at 5100. Your Block Size can be different if you want, as long as it divides evenly by 80.
  • RECORD FORMAT this should be set to FB (fixed block), not VB (variable blocks) for reasons that should be obvious giving everything described above. Getting this wrong created some really interesting chaos on compile. At first it looked like z/OS COBOL compiler was just a little more anal about indentation than GnuCOBOL is, but after a couple rounds of fiddling with the indentations I realized that the compiler was ignoring line breaks, producing the following errors:
a blank character was missing before character ”.” Non-COBOL characters were found starting with “.” characters were discarded,

Yak 03: Line Commands -vs- Command Commands

Data set properly allocated it’s time to start writing some COBOL.

a blank file full of possibilities

Yak 04: Compile, Link, Load

It’s probably not fair to refer to z/OS as legacy, but it definitely retains some legacy paradigms which take some getting used to. When it comes to compiling and running a program you have to tell the mainframe to do each step, it assumes nothing, whereas modern development tools tend to default towards automating the steps you’re most likely going to want to do together and adding flags to break things out if that’s desired.

Linkage Editor

Yak 05: Working with Spools (Bonus Yak!)

There are some inefficiencies to our approach here. JCL scripts not only allow us to do all three steps in one job, but the output of one can be directed into the input of the other thereby creating temporary data sets where this manual process created more permanent ones. By using the TSO command CALL our output is just dumped directly to stdout, but a normal COBOL program that is compiled and run with JCL would likely send its output to the spool. Even though we don’t cover JCL in this post, it’s worth taking you through the spool interface anyway. It will come in handy later on.

Going Forward

Most of this stuff was pieced together through trial and error. I will update this post as my understanding evolves. I’m sure the simple act of writing this all down and putting it on the internet will bring out all sorts of people who will contribute more detail. Corrections and clarifications are welcome in the comments!

Helpful Resources:



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Marianne Bellotti

Author of Kill It with Fire Manage Aging Computer Systems (and Future Proof Modern Ones)