Application Development Using C/C++
Part Three - Challenge #06

Background:

C and C++ can be compiled and executed using either JCL or Unix System Services shell. C and C++ in the z/OS environment can read, write, and update any of the z/OS data sources. The IBM z/Architecture enables z/OS XL C/C++ development of high-performing business applications.

The challenge is designed to demonstrate z/OS flexibility with C and C++ programs.

Your participation in Part 3 enables you to claim z/OS experience. A detail of claiming z/OS experience is the ability to locate the professional documentation related to any specific z/OS technical discipline. Below is the URL for the IBM z/OS XL C/C++ professional documentation.

z/OS XL C/C++ Professional Documentation

Challenge:

Review the C program source code in the wikipedia URL that follows:
wikipedia C program example

The C program source was pasted into a z/OS data set member to be used in the challenge.

Brief description of the example C program syntax
  • #include stdio.h includes functions involving file input and output
    stdio.h
    fopen, fclose, fputs, getc used in the program is available from header, stdio.h
  • #include stdlib.h includes functions involving memory allocation, process control, conversions, etc.
    stdlib.h
    int used in the program is available from header, stdlib.h
  • char buffer[5] allocate memory for a character array of 5
  • for loop is getting 5 characters, getc, and writing each character to buffer[i]
      where the i in buffer[i] is 1 thru 5
  • printf writes the hexadecimal, %x, value for each character in the respective buffer[ ] array

The challenge will compile the C program into a unix file executable, then again compile the C program into an MVS data set member executable. Just wanted you to know that z/OS flexibility makes it possible to copy the executable between unix and MVS data sets without the need to recompile.

FYI - It is possible to cut and paste the commands in most cases.

  • Compile and execute C1 using Unix shell prompt
    1. Shell prompt access as follows:
      tso omvs
    2. Copy C program from MVS data set member to Unix file
      cp "//'zos.mtm2017.public.source(c1)'" c1.cpp
    3. Copy C program input data from MVS data set member to Unix file
      cp "//'zos.mtm2017.public.data(myfile)'" myfile
    4. Compile C program to unix executable
      c++ -+ -o c1 c1.cpp
    5. Execute the C program executable that reads myfile
      ./c1
    6.     myfile content is 123abc456def
          program c1 reads 5 characters only, 1 character at a time, then prints the character hexadecimal value
    7. exit, then enter to return to ISPF panels

  • Compile and execute C1 using JCL
    1. EDIT hlq.SOURCE and select s new member C1
    2. Copy C program to new member C1 as follows:
      copy 'zos.mtm2017.public.source(c1)'
    3.     Identical source compiled and executed from unix shell prompt
          enter hilite c to hilite C reserved words
    4. EDIT hlq.JCL and select s new member P3CH6
    5. Copy JCL to compile and execute C1 program as follows:
      copy 'zos.public.jcl(p3ch6)'
          enter hilite JCL to hilite JCL reserved words
    6. Submit JCL and review job output in SDSF
      submit; =sd; st

    7. P3CH6 JCL job output shows a problem with execution of the C1 program

  • Execute C1 program using TSO/ISPF interactive session
    1. You can observe the problem by executing the C1 program interactively from =6 ISPF panel as follows:

    2. Edit hlq.SOURCE member C1 and make the following modification:
       Old
      fopen("myfile", "rb");
       New
      fopen("/z/public/myfile", "rb");
    3. =6 to save, exit, and jump to ISPF Command Shell panel

    4. Recompile the modified C1 source as follows:
      tso submit jcl(p3ch6)

    5. You can observe the modification by executing the C1 program interactively from =6 ISPF panel as follows:

  • C/C++ program can read, write, and update unix file systems and MVS data sets interchangebly without code modification.

    The C1 program was modified hard coding a unix file name, /z/public/myfile, in the source.
    Best practice is to use JCL capability to redirect internal file name myfile to a physical resource, such as /z/public/myfile, or an MVS data set name.

    You previously learned how. Here is a refresher:
    1. Edit hlq.SOURCE member C1 and make the following modification:
       Old
      fopen("/z/public/myfile", "rb");
       New
      fopen("DD:myfile", "rb");
      =3.4 to save, exit, and jump to data set list panel


    2. Edit hlq.JCL member name P3CH6 adding a new DD statememt as follows:
        Enter caps off because lower case will be entered into the JCL stream.
        Modify JCL as follows:

      Old
      New
      The above submit; =6 results in a compile and jump to ISPF Command Shell panel.

    3. You can validate P3CH6 compiled and executed successfully as follows:

      The above allocate command is equivalent to a JCL job DD statement for interactive execution.

      Interactively execute the C1 program to read from path('/z/public/myfile') by way of file(myfile) as follows:

    4. Note: If the above failed to execute properly, then correct C1 source and submit P3CH6 JCL to compile and execute.

      Helpful Hint: After modification of C1 source, then from edit session enter the following:

      The above will save source modifications, submit JCL to compile C1 source changes, jump to SDSF status display.

  • The final task in the challenge is to modify hlq.SOURCE member C1 source code to accomplish the following:
    1. Read and print 10 characters, 0 thru 9.
        Original C1 source is reading and printing 5 characters, 0 thru 4
    2. Print the 10 characters in character format.
        Original C1 source is printing characters in hexadecimal format, %x
      Hint: Search for "c printf format specifiers"

    See above screen shot with method to save, tso submit, and review output following edit.

    Note: If the above failed to print requested output, then correct C1 source and submit P3CH6 JCL to compile and execute.

    Once JCL P3CH6 execution of C1 is printing the first 10 characters in character format, then write the JCL job "RUN" step output to hlq.P3.OUTPUT(#06) as follows:


    xdc will present panel below to update with output location.

Review hlq.P3.OUTPUT(#06) to verify C1 output exists.

If struggling with compile errors:

  • buffer size from 5 to 10
  • loop from 5 to 10
  • printf printing 10 buffers in character format
  • printf commas and termination can be an easy mistake to make

Next: Challenge #07