ISPF reflists provide hot lists of datasets and files.

You can set up hot lists of data sets names to make it easier to use data sets and files in Unix Services. For example if your hot list of data sets is SYS1.PROCLIB, ADCD.Z245.PROCLIB, COLIN.PROCLIB, COLIN.C.SOURCE, you can get a list of these in ISPF 3.4 format, so you can quickly move between them, rather than have to keep using ISPF 3.4 and typing in the names of the data sets.

ISPF provides a list called REFLIST with the last 30 datasets or Unix files you referenced, so when you come back from holiday and cannot remember what you were working on, then the REFLIST will show you. Recalling Those Darn Dataset Names is an interesting article.

You can have a hot list of Unix Services files.

You can use the REFLISTD command, or go into ISPF 3.4, up to the action bar, and use the pull down to select REFLIST.
By default, this gives you the a list of the last 30 data sets you used.

Example output

File View Options Help .
────────────────────────────────────────────────────────────────────────────── .
ISRPDSNL Personal Data Set List DSLIST processed .
Command ===> 
Enter a list action to perform or select a data set entry to retrieve. .
Action: S=Save A=Save As D=Delete this list E=Extended Edit L=DSLIST U=UDLIST .
.
Action   Name    Description                  Created Referenced .
L        REFLIST Last 30 referenced data sets         22/04/26 11:45 .

Select Data Set, DSLIST Level or z/OS UNIX file Volume WS 
. 'COLIN.CBT503.FILE967' 
. 'USER.Z24C.CLIST' 
. 'COLIN.SRCHML.LIST' 
. 'COLIN.ZLOGON.CLIST' 
. /u/tmp/zpymqi/code/pymqi/MQMAP.h 
. 'COLIN.CUCI.EXEC' 

The data at the bottom of the display is what is in this list. You cannot do anything with these entries. You can have datasets as well as Unix files in the list

The action only applies to the List entry itself.

If you put an L in front of the REFLIST, you get into standard ISPF 3.4 data set list – with all of the data sets from the list. You can use all of the commands you know and love from this list. You can use option U to list all of the Unix files in the list.

You can also save this list, for example use “A” to create your own list (eg COLIN).

If you want to use this list you can use the command REFACTD COLIN, or go to ISPF 3.4, action bar, REFLIST

1. Current Personal Data Set List (COLIN)
2. List of Personal Data Set Lists

Option 2 gives

ISRPLTAB EFLIST             Personal Data Set Lists                List 1 of 2
Command ===>                                                  Scroll ===> PAGE
                                                                               
Action: O=Open  A=Save As  D=Delete  E=Edit  L=DSLIST  U=UDLIST               
                                                                               
Name      Description                  Created  Referenced
_ COLIN   colin's list                 22/04/26 22/04/26 11:55
_ REFLIST Last 30 referenced data sets          22/04/26 11:57
End

This allows you to pick a list, and specify if you want a data set list, or a Unix file list.

This is really handy – but not very well documented. It feels like it has not been written for the end users but from the IBM developers view point.

Configuring ISPF for new applications.

I found an interesting ISPF extension which I wanted to try out. But I could not find any documentation on how to install it. As usual I found out even more interesting stuff trying to document it.

Logging on to TSO.

When you logon to TSO you specify a procedure such as ISPFPROC. This procedure is in the SYS1.PROCLIB concatenation.  A user can have a default procedure specified in the RACF TSO segment. A user is given access to the RACF CLASS TSOPROC. (So you use a command like RDEFINE TSOPROC NEWPROC UACC(READ) )

This procedure allocates the datasets used by TSO and ISPF, for example ISPPLIB, ISPMLIB, ISPLLIB,ISPEXEC, SYSEXEC, SYSOUT.

If you are authorised you can create your own TSO procedure, and add your application’s data sets to the JCL. Most systems do not allow this.

When this JCL is executed you can pass parameters to it, for example

//ISPFPROC EXEC PGM=IKJEFT01,REGION=0M,DYNAMNBR=200,
//             PARM=’%ISPFCL’                       

will cause the ISPFCL exec or clist to be executed.   This is usually in the SYS1.CLIST concatenation. You can specify PARM=’EXEC ”SYS1.CLIST(SPFALLOC)”’ and specify a data set.

You can use this

  1. To write a message to users
  2. Allocate additional data sets,
  3. Check the existence of a profile, and execute it.

User specific processing

With the clist specified in the PARM statement you can have code like

/* rexx */
address TSO
userid = userid()
zl =”‘”userid”.ZLOGON.CLIST'” /* so we get ‘colin.zlogon.clist’ */
if SYSDSN(zl) = “OK” then exec zlogon /* the userid.. and .clist default’ */

For my userid this would check to see if COLIN.ZLOGON.CLIST exists, and if so, it executes it.

userid.ZLOGON.CLIST

Within this data sets you can have user specific processing, for example

/* Rexx */
say "in colin.zlogon.clist"
address ispexec
"LIBDEF ISPLLIB DATASET ID('COLIN.ISPF.ISPLLIB') STACK"
"LIBDEF ISPMLIB DATASET ID('COLIN.CUCI.ISPMLIB') STACK"
"LIBDEF ISPPLIB DATASET ID('COLIN.CUCI.ISPPLIB') STACK"
"LIBDEF ISPTLIB DATASET ID('COLIN.CUCI.ISPTLIB') STACK"
address tso "ALTLIB ACTIVATE APPLICATION(CLIST)
DATASET('COLIN.CUCI.EXEC') "

This will add the datasets to the specified library, for example adds the panel library COLIN.CUCI.ISPPLIB to ISPPLIB.

You can use “LIBDEF ISPPLIB” to “pop” the definitions back to what they were before the call.

Running your own application

If you have your own panel or application you want to use, you could use the following to set up the libraries and display Mypanel

address ispexec
"LIBDEF ISPLLIB DATASET ID('COLIN.ISPF.ISPLLIB') STACK"
"LIBDEF ISPMLIB DATASET ID('COLIN.CUCI.ISPMLIB') STACK"
"LIBDEF ISPPLIB DATASET ID('COLIN.CUCI.ISPPLIB') STACK"
"LIBDEF ISPTLIB DATASET ID('COLIN.CUCI.ISPTLIB') STACK"
address tso "ALTLIB ACTIVATE APPLICATION(CLIST)
DATASET('COLIN.CUCI.EXEC') "
"SELECT PANEL(Mypanel ) NEWAPPL(MYA) PASSLIB"
/* afterwards reset things back */
address tso "ALTLIB DEACTIVATE APPLICATION(CLIST)"
"LIBDEF ISPLLIB"
"LIBDEF ISPPLIB"
"LIBDEF ISPMLIB"
"LIBDEF ISPTLIB"

What has been libdef-ed?

You can use the TSO command ISPLIBD to display the data sets that have been libdef-ed for the logical screen. Note each logical screen can have its own libdef statements – depending on the set up. See here for a description.

I’ve run out of space on z/OS – what is using it all?

I hit this problem when trying to backup some data sets. There was plenty of free space on some of the volumes, but not much free space on the “user” volumes.

You can use ISPF 3;4 to list data sets on a volume or with a specified high level qualifier. You can use the sort command, for example sort tracks. This reports on number of tracks allocated sorted in descending size. You can deletes unwanted data sets.

If you go to ISPF 3;4 and specify option V for VTOC, and specify a Volume Serial, you can display information about the volume.

If you are running in Unix Services

du -a ./ | sort -n -r | head -n 30

Gives the top 30 files or directories

Old dogs, new tricks, ISPF compare

When looking for a comparison facility for Unix files, I stumbled across ISPF edit compare function.

If you are editing a file you can use the compare * command to show the changes you made to the file in the current session. This gave me

000001 line 1
====== line 3
.OAAAA line 2
.OAAAB line 4
.OAAAC line 5

Where

  • line 1 was unchanged
  • line 3 was deleted
  • line 2,4,5 were added

You can then use “mm” or “mdd …. mdd” prefix commands on the ====== to apply the changes to the file, and use “d” or “dd … dd” on the .O prefix lines to delete the lines.

You can use the compare command, and be prompted for options.
I specified a Unix file, and could see the differences.

You can set the exclude option (at the bottom of the panel), which says exclude all the lines, but display ‘n’ lines around changes, where ‘n’ is specified at the top of the panel.

One funny….

I noticed that compare was display “blank” lines in Unix files as being changed. The original file had a null line, with just an end of line. When I customised the file and saved it, ISPF replaces an “end of line” with “blank end of line”. As these do not match, they show up as being changed.

The solution is to edit the original file with null lines, make a dummy change, and save the file. The file will no longer have null lines, and only your changes will be visible.

ASCII files in OMVS

I found I was unable to compare python source files in OMVS, because they were ASCII files. (When the files were tagged as ASCII, I could edit them).

You cannot use ISPF compare if the files are ASCII (non EBCDIC). You can do

Compare the files then use the following to transform them back.

The power of exclude in ISPF edit

I hope most people know about the ISPF edit exclude facility.  You can issue commands like

X ALL /* exclude every thing */
F XXXX ALL
F YYYYY ALL WORD
DELETE ALL X /* delete everything which is excluded */
RESET
X ALL
F ZZZZ all
F AAAA all
FLIP /* make the excluded visible, and the displayed hidden */
CHANGE 'ABC' 'ZYX' ALL NX /* do not change hidden lines */

You can also exploit this in macros.  See ISREDIT XSTATUS.

/* rexx */ 
ADDRESS ISPEXEC
'ISREDIT MACRO'
"ISREDIT EXCLUDE 'AAA' ALL PREFIX" /* just like the command*/
"ISREDIT LOCATE .ZLAST" /* go to the last line */
"ISREDIT (r,c) = CURSOR" /* get the row and column number */
/* r has the row number of the last line */
do i = 1 to r
"ISREDIT (xnx) = XSTATUS "i
say "Line exclude status is" i xnx
"ISREDIT (line) = LINE " i /* extract the line */
if (...) then
"ISREDIT XSTATUS "i" = X" /* exclude it */
end

You can also see if a line has been changed this edit session:

"ISREDIT (status) = LINE_STATUS "i /* for line i */
if (substr(status,8,1) = '1') then
say "Line" i " was changed this session "

 

 

How to capture TSO command output into an ISPF edit session

One way of doing this, is to run a TSO command in batch, use SDSF to look at the output, and then use SE to edit the spool file.

This was too boring, so I wrote a quick macro ETSO

/* REXX /  parse source p1 p2 p3 p4 p5 p6 p7 env p9  
if env = "ISPF" then  
do    
  ADDRESS ISPEXEC    
  "ISREDIT MACRO (cmd ,REST)"  
end  
else  
do
    Say "This has to run from an ISPF edit session " 
   return 8;  
end  
/* prevent auto save … user has to explicitly save or cancel*/  
"ISREDIT autoSave off prompt"  
x = OUTTRAP('VAR.')  
address tso   cmd rest  
y = OUTTRAP('OFF')  
/* insert each record in turn last to first at the top of the file */ 
do i = var.0 to 1 by -1 
  "ISREDIT LINE_AFTER 0  = '"var.i"'" 
end 
exit

This macro needs to go into a dataset in SYSEXEC or SYSPROC concatenation – See TSO ISRDDN. I typed etso LU in an edit session, and it inserted the output of the TSO LU the top of the file.

For capturing long lines of output, you’ll need to be in a file with a long record length.

Neat!

To create a temporary dataset to run the above command I created another rexx called TEMPDSN

/* REXX */
parse source p1 p2 p3 p4 p5 p6 p7 env p9
if env = "ISPF" then
do
  ADDRESS ISPEXEC
  "ISREDIT MACRO (cmd ,REST)"
end
else
do
  Say "This has to run from an ISPF session "
  return 8;
end
u = userid()
address TSO "ALLOC DSN('"u".temptemp') space(1,1) tracks NEW DELETE ",
"BLKSIZE(1330) LRECL(133) recfm(F B) DDNAME(MYDD)"
if (rc <> 0) then exit
address ISPEXEC "EDIT DATASET('"u".temptemp')"
address TSO "FREE DDNAME(MYDD)"

You can then do even cleverer things by having TEMPDSN calling ETSO as a macro, and passing parameters using the ISPF variable support from the TSO command line.

Updated TEMPDSN, changes in bold.

/* REXX */ 
parse source p1 p2 p3 p4 p5 p6 p7 env p9
say "env" env
if env = "ISPF" then
do
ADDRESS ISPEXEC
"ISREDIT MACRO (cmd ,REST)"
end
else
do
Say "This has to run from an ISPF session "
return 8;
end
tempargs = ""
/* if we were passed any parameters */

parse arg args
if ( length(args) > 0) then
do
tempargs = args
"VPUT tempargs profile"
end

u = userid()
address TSO "ALLOC DSN('"u".temptemp') space(1,1) tracks NEW DELETE ",
"BLKSIZE(1330) LRECL(133) recfm(F B) DDNAME(MYDD)"
if (rc <> 0) then exit
address ISPEXEC "EDIT DATASET('"u".temptemp') MACRO(ETSO)"
address TSO "FREE DDNAME(MYDD)"

if ( length(tempargs) > 0) then
do
"VERASE tempargs profile"
end

and the macro ETSO has

/* REXX */ 
parse source p1 p2 p3 p4 p5 p6 p7 env p9
if env = "ISPF" then
do
ADDRESS ISPEXEC
"ISREDIT MACRO (cmd ,REST)"
end
else
do
Say "This has to run from an ISPF edit session "
return 8;
end
/* prevent auto save ... user has to explicitly save or cancel*/
"ISREDIT autoSave off prompt"
if (length(cmd) = 0) then
do
"VGET tempargs " PROFILE
if (rc = 0) then
cmd = tempargs
end
x = OUTTRAP('VAR.')
address tso cmd rest
y = OUTTRAP('OFF')
/* insert each record at the top of the file */
do i = var.0 to 1 by -1
"ISREDIT LINE_AFTER 0 = '"var.i"'"
end
EXIT

From ISPF 6, a TSO command line, I issued tempdsn racdcert list certauth  and it gave me the file with the output from the command, and the file has record length of 133.  If you try to  save the data,  the data set will be deleted on close.

 

 

How do I do things with a subset of PDS members matching a pattern?

There are some clever things you can do on a subset of members of a PDS.

If you use ISPF  (Browse) or ISPF 2 (Edit) you can specify a data set name of

  • ‘COLIN.AAA.PROCLIB(%%%%%%00)’ and it displays only the members ending in 00.
  • ‘COLIN.AAA.PROCLIB(*AH*)’ to display all member with an AH in the name.
  • ‘COLIN.AAA.PROCLIB’  for all of the members.

If you use ISPF 3;4 I havent found a way of doing the same.

Acting on a subset.

If you have a list of members, for example ISPF 1,2,3;4  you can issue a primary command

sel *99 e 

which says select all those members ending in  99, and use the command “e” in front.  Similary  sel %%%%%%00 b.

Sorting the list

You can sort the list by many fields, name, size last changed.  For example “Sort Name”.

I have “Tab to point-and-shoot fields” enabled.   I can tab to column headers, and press enter.   The rows are sorted by this column.

I often use “sort changed” to find the ones I changed recently, and “sort id” to see who else has been changing the members.

Srchfor

I use “srchfor ” or “srchfor value” to look for the members containing a string (or two).

When this command has completed tab to “prompt” and press enter, or enter “sort prompt” to sort the members with hit to the top of the list.

Refresh

If the member list has changed, you can use “refresh” to refresh it.