Joined: 30 Nov 2013 Posts: 917 Location: The Universe
Lynne Schuler wrote:
... or is the only way to do this is through an assembler program using the RDJFCB macro? ...
Yes, but indirectly. See the topic "Type 13 JFCB Exit List Entry" in DFSMSdfp Advanced Services for your z/OS release to retrieve all the JFCBs for a concatenation. While it is possible to retrieve the JFCB for additional data sets in a concatenation using the traditional RDJFCB macro, it is moderately difficult and requires you to do some fakery. It requires detailed knowledge of what a DCB looks like after OPEN, and some detailed knowledge of the structure of the TIOT.
I am trying to decipher how a very old program does this. but, as I'm going through this, I'm thinking.. there has got to be a better way. A lot has changed in 10, 15 years. this program uses a type 7 JFCB exit list entry, then gets the information for each DSN by jumping from the dcb to the deb to the ucb for each DSN, via the header exit routine.
I saw the type 13 JFCB exit list entry, but I couldn't find an example of how to use it. Do you know of any example that I could look at of how it would be set up and executed?
Joined: 30 Nov 2013 Posts: 917 Location: The Universe
This is a complete example, easily callable from Cobol -
Code:
GETDINFO TITLE ' O B T A I N D A T A S E T >
I N F O R M A T I O N'
***********************************************************************
* *
* Title - GETDINFO *
* *
* Function / Operation - GETDINFO retrieves allocation information *
* for all data sets in a concatenation. *
* *
* Calling Sequence - *
* CALL GETDINFO,(OUTPUT,NUMDS,DDNAME) *
* ... *
* OUTPUT DC 10CL50' ' *
* OUTPUTN EQU (*-OUTPUT)/L'OUTPUT *
* NUMDS DC A(OUTPUTN) *
* DDNAME DC CL8'DDNAME' *
* *
* The NUMDS data area is replaced with the number of entries in *
* OUTPUT that are actually filled in. It is set to 0 if the RDJFCB *
* macro failed. If there are more data sets in the concatenation *
* than specified by NUMDS, NUMDS is not altered, and only NUMDS *
* entries in OUTPUT are filled in. *
* *
* Attributes - GETDINFO is reenterable, refreshable and reusable. *
* Its intended operating environment is task mode, enabled, problem *
* state and problem key. GETDINFO will operate in any RMODE and *
* AMODE consistent with the AMODE of the caller, and the actual *
* location of the save area, parameter list, and data areas *
* specified by the parameter list. *
* *
* Language Environment - GETDINFO is LE compstible but not LE *
* compliant. It will operate in an LE environment and not damage *
* the environment. The LE environment is completely restored *
* before GETDINFO returns. *
* *
***********************************************************************
SPACE 5
GETDINFO RSECT Define program CSECT
GETDINFO AMODE ANY
GETDINFO RMODE ANY
PUSH PRINT
PRINT NOGEN
DCBD DSORG=QS,DEVD=DA
SPACE 2
PRINT GEN
IHAARA
PRINT NOGEN
SPACE 2
JFCB DSECT Define JFCB data area
IEFJFCBN ,
SPACE 2
WA DSECT Define GETDINFO work area
SAVEAREA DS 9D 72 byte save area
OPARMS RDJFCB (*-*,INPUT),MF=L RDJFCB parameter list
OPARM EQU OPARMS,*-OPARMS
BPAMDCBS DCB DSORG=PO,MACRF=R,DDNAME=FILLMEIN,EXLST=*-*
BPAMDCB EQU BPAMDCBS,*-BPAMDCBS
XLIST DS A(*-*) Exit list
PRINT GEN
WAARLS IHAARL DSECT=NO,DESCR=NO Allocation retrieval list
WAARL EQU WAARLS,*-WAARLS
PRINT NOGEN
DS 0D
WASIZE EQU *-WA Work area size
POP PRINT
EJECT
GETDINFO RSECT Return to program CSECT
USING *,10 Establish program addressability
USING WA,13 Establish work area addressability
SAVE (14,10),,'GETDINFO &SYSDATE &SYSTIME' Save registers
LR 10,15 Prepare program base register
LM 6,8,0(1) Load the parameter list
LA 5,WASIZE Allocate the work area below
GETMAIN R,LV=(5) the line
LR 4,1 Copy the work area address to reg 4
SR 15,15 Clear the work area
MVCL 4,14
ST 13,(SAVEAREA-WA)+4(,1) Add the new save aarea
ST 1,8(,13) to the save area chain
LR 13,1 Prepare new save area pointer
MVC OPARM,MASTOPEN Prepare the
MVC BPAMDCB,MASTDCB data areas
MVC WAARL,MASTARL for RDJFCB
LA 0,WAARL
ST 0,XLIST
MVI XLIST,X'80'+X'13'
MVC (DCBDDNAM-IHADCB)+BPAMDCB,0(8) Copy the DD name to ->
the DCB
LA 0,XLIST Store the exit list address in the
ICM 0,B'1000',(DCBEXLST-IHADCB)+BPAMDCB DCB, taking care
STCM 0,B'1111',(DCBEXLST-IHADCB)+BPAMDCB not to alter ->
the high order ->
byte
RDJFCB BPAMDCB,MF=(E,OPARM) Read the JFCBs
LTR 15,15 RDJFCB OK?
BZ GENDATA Yes
SR 0,0 Reset NUMDS
ST 0,0(,7)
LA 15,4 Set RC = 4
B EXIT
GENDATA NOPR 0
LH 3,ARLRTRVD Load data sets in concatenation
l 4,0(,7) Load output slots
CR 3,4 Compare data sets w/ output slots
BH RESET3 Br if more data sets than ->
output slots
LR 4,3 Reset output slots
B SAVE4
RESET3 LR 3,4 Use defined output slots
SAVE4 ST 4,0(,7) Reset NUMDS
L 1,ARLAREA Load address of the first ARA
USING ARA,1 Establish ARA addressability
SCANARA MVC 0(L'JFCBDSNM,6),(JFCBDSNM-JFCB)+ARAJFCB Copy DSNAME
MVC L'JFCBDSNM(6,6),(JFCBVOLS-JFCB)+ARAJFCB and first vol
LA 6,L'JFCBDSNM+6(,6) Compute addr of next output area
AH 1,ARALEN Compute addr of next ARA
BCT 4,SCANARA Do the next ARA
DROP 1 Kill ARA addressability
L 0,ARLPOOL Free the JFCBs built by RDJFCB
L 1,ARLAREA
FREEMAIN R,LV=(0),A=(1)
SR 15,15 Set RC = 0
EXIT LR 8,15
LR 1,13
L 13,SAVEAREA+4
LA 0,WASIZE
FREEMAIN R,LV=(0),A=(1)
LR 15,8
RETURN (14,10),T,RC=(15)
PUSH PRINT
PRINT NOGEN
MASTDCB DCB DSORG=PO,MACRF=R,DDNAME=FILLMEIN,EXLST=*-*
MASTOPEN RDJFCB *-*,MF=L
MASTARL IHAARL DSECT=NO,DESCR=NO,PREFIX=MRL
POP PRINT
DC 0D'0'
DROP ,
END ,
That is nice - even to use as a utility from an assembler program. Why reinvent the wheel when you can use something like this? Nice
However, I have a question. Would I need to close then open the file again in my program to start reading the records from the concatenated input file?
and, if I have an exlst defined with a header routine and trailer routine, will that allow me to keep track of the counts of certain items within each DSN?
In this application, the input file consists of different files from different entities, and it gives each "user" a report on how many errors were in their file, and some other counts, as well as total counts. It is in essence a file of "requests" from these different users.
so, even though I could use this routine to get the physical information on each file, can I still know when reading each input record when one dsn ends,and another begins?
Joined: 30 Nov 2013 Posts: 917 Location: The Universe
Lynne Schuler wrote:
That is nice - even to use as a utility from an assembler program. Why reinvent the wheel when you can use something like this? Nice
However, I have a question. Would I need to close then open the file again in my program to start reading the records from the concatenated input file?
GETDINFO does not open the concatenation; it just obtains the JFCBs to obtain the data set names and volume serials. While there are similarities in GETDINFO to opening a data set: the parameter list for RDJFCB is identical to the parameter list for OPEN, and RDJFCB requires a DCB, just like OPEN, RDJFCB is just a service that is independent of OPEN.
While the documentation for GETDINFO shows its use from another Assembler program, it was designed so it could be readily usable from a Cobol program. I don't do Cobol, so I can't help you there, nor could I test it in that environment.
Lynne Schuler wrote:
and, if I have an exlst defined with a header routine and trailer routine, will that allow me to keep track of the counts of certain items within each DSN?
One weakness in the concatenation scheme is it is difficult for an application program to know when it transitions to a new data set in the concatenation. By "exlst" I presume you mean "exit."
Lynne Schuler wrote:
In this application, the input file consists of different files from different entities, and it gives each "user" a report on how many errors were in their file, and some other counts, as well as total counts. It is in essence a file of "requests" from these different users.
so, even though I could use this routine to get the physical information on each file, can I still know when reading each input record when one dsn ends,and another begins?
An Assembler program with direct access to the DCB can determine when the data set transition occurs by looking at the DCBTIOT data area. I'm not sure how reliable this would be for a program using QSAM, but it would be reliable for a program using BSAM.
Joined: 30 Nov 2013 Posts: 917 Location: The Universe
This is a refined version. The lead comments are unchanged, so they are not repeated. One serious bug has bug has been corrected in this version. I will leave it to the lurkers here to figure out the bug. The size of the work area has been significantly reduced - not that that was a serious issue.
Code:
GETDINFO TITLE ' O B T A I N D A T A S E T >
I N F O R M A T I O N'
GETDINFO RSECT Define program CSECT
GETDINFO AMODE ANY
GETDINFO RMODE ANY
PUSH PRINT
PRINT NOGEN
DCBD DSORG=QS,DEVD=DA
SPACE 2
PRINT GEN
IHAARA
PRINT NOGEN
SPACE 2
JFCB DSECT Define JFCB data area
IEFJFCBN ,
SPACE 2
WA DSECT Define GETDINFO work area
OPARMS RDJFCB (*-*,INPUT),MF=L RDJFCB parameter list
OPARM EQU OPARMS,*-OPARMS
BPAMDCBS DCB DSORG=PO,MACRF=R,DDNAME=FILLMEIN,EXLST=*-*
BPAMDCB EQU BPAMDCBS,*-BPAMDCBS
XLIST DS A(*-*) Exit list
PRINT GEN
WAARLS IHAARL DSECT=NO,DESCR=NO Allocation retrieval list
WAARL EQU WAARLS,*-WAARLS
PRINT NOGEN
DS 0D
WASIZE EQU *-WA Work area size
POP PRINT
EJECT
GETDINFO RSECT Return to program CSECT
USING *,6 Establish program addressability
USING WA,5 Establish work area addressability
SAVE (14,6),,'GETDINFO &SYSDATE &SYSTIME' Save registers
LR 6,15 Prepare program base register
LM 2,4,0(1) Load the parameter list
LA 0,WASIZE Allocate the work area below
GETMAIN R,LV=(0) the line
LR 5,1 Copy the work area address to reg 5
MVC OPARM,MASTOPEN Prepare the
MVC BPAMDCB,MASTDCB data areas
MVC WAARL,MASTARL for RDJFCB
LA 0,WAARL
ST 0,XLIST
MVI XLIST,X'80'+X'13'
MVC (DCBDDNAM-IHADCB)+BPAMDCB,0(4) Copy the DD name to ->
the DCB
* Store the exit list address in the DCB, taking care not to alter
* the high order byte of DCBEXLST
LA 0,XLIST
STCM 0,B'0111',(DCBEXLSA-IHADCB)+BPAMDCB
RDJFCB BPAMDCB,MF=(E,OPARM) Read the JFCBs
LTR 15,15 RDJFCB OK?
BNZ SETRC4 No
GENDATA LH 14,ARLRTRVD Load data sets in concatenation
ICM 15,B'1111',0(3) Load output slots
BP TESTSIZE Br if output slots > 0
SETRC4 LA 15,4 Set RC = 4
SR 0,0 Set NUMDS = 0
ST 0,0(,3)
B EXIT
TESTSIZE CR 14,15 Compare data sets w/ output slots
BNH SAVEREG Br if data sets <= output slots
LR 14,15 Use number of slots
SAVEREG ST 14,0(,3) Update output slots used
L 1,ARLAREA Load address of the first ARA
USING ARA,1 Establish ARA addressability
SCANARA MVC 0(L'JFCBDSNM,2),(JFCBDSNM-JFCB)+ARAJFCB Copy DSNAME
MVC L'JFCBDSNM(6,2),(JFCBVOLS-JFCB)+ARAJFCB and first vol
LA 2,L'JFCBDSNM+6(,2) Compute addr of next output area
AH 1,ARALEN Compute addr of next ARA
BCT 14,SCANARA Do the next ARA
DROP 1 Kill ARA addressability
L 0,ARLPOOL Free the JFCBs built by RDJFCB
L 1,ARLAREA
FREEMAIN R,LV=(0),A=(1)
SR 15,15 Set RC = 0
EXIT LR 2,15 Copy return code to reg 2
LA 0,WASIZE Load length of the work area
FREEMAIN R,LV=(0),A=(5) Free the work area
LR 15,2 Copy return code to reg 15
RETURN (14,6),T,RC=(15) Restore registers & return
PUSH PRINT
PRINT NOGEN
MASTDCB DCB DSORG=PO,MACRF=R,DDNAME=FILLMEIN,EXLST=*-*
MASTOPEN RDJFCB *-*,MF=L
MASTARL IHAARL DSECT=NO,DESCR=NO,PREFIX=MRL
POP PRINT
DC 0D'0'
END ,
This is an old program that I'm trying to "update" (comment, and make sure it keeps running). Actually.. what it does is pretty simple:
old code (original from 1996)
Code:
* executed via header routine: before first get of each
* Concatenated DSN
RDJFCB INconcat RDJFCB MACRO
LA R5,INconcat DCB ADDR
L R14,44(R5) GET DEB ADDR
L R14,32(R14) GET UCB ADDR
MVC 40(6,R1),28(R14) VOLUME SERIAL NUMBER
MVC 5(35,R1),INDSN DSN FROM RDJFCB MACRO
OI 48(R5),X'08' SET DCBOFLGS FOR UNLIKE ATTRBS
EXLST DC X'01',AL3(HDR)
DC X'03',AL3(TLR)
DC X'87',AL3(INDSN) FOR RDJFCB MACRO
with my comments and using IBM dsects. Executable Object is equal to the old program.
Code:
RDJFCB INconcat RETRIEVE IN_concat INFO INTO JFCBIN
OPEN INconcat OPEN INPUT FILE
L R14,SAVE141
BR R14
*---------------------------------------------------------------
* do this before the 1st get for each DSN of a concatenated
* input file
* SEE USING THE DEB AND THE DCB TO FIND THE UCB ADDRESS
* IN IBM MANUAL:
* 'Z/OS MVS PROGRAMMING: AUTHORIZED ASSEMBLER SERVICES GUIDE'
*---------------------------------------------------------------
LA R5,INconcat DCB ADDR
USING IHADCB,R5 USE IBM DSECT FOR DCB AREAS
L R14,DCBDEBAD DEB ADDR (FROM DCB)
USING DEBDASD,R14 DIRECT-ACCESS STORAGE DEVICE
L R14,DEBUCBA UCB ADDRESS (FROM DEB)
MVC MBE@VOLSER,28(R14) SAVE VOLUME SERIAL NUMBER
*LS* what UCB dsect here?
MVC MBE@DSNAME,JFCBDSNM MOVE IN DSNAME FROM JFCB INFO
*LS* MVC 5(44,R1),JFCBDSNM WHY NOT USE COMPLETE DSNAME?
OI DCBOFLGS,DCBOFPPC IN DCB, INDICATE CONATENATION OF
* FILES WITH UNLIKE ATTRIBUTES
*===========================================================================
DS 0F
EXLST DC X'01',AL3(HDR) INPUT HEADER LABEL SUBROUTINE
DC X'03',AL3(TLR) INPUT TRAILER LABEL SUBROUTINE
DC X'87',AL3(IN01JFCB) TYPE 07 JFCB EXIT LIST ENTRY
* DCB INFO READ INTO IN01JFCB
DS 0F
IN01JFCB DS 0XL176 MUST BE 176 BYTES ON F B
IEFJFCBN LIST=YES IBM MACRO DEFINING JFCB FIELDS
Joined: 30 Nov 2013 Posts: 917 Location: The Universe
The UCB macro is IEFUCBOB, the base address is UCBOB.
As coded, your code must be AMODE 24.
This is safer -
Code:
L 14,(DCBDEBAD-IHADCB)+dcb Load address of the DEB
N 14,=A(X'FFFFFF') Isolate the 24-bit DEB address
LA 14,DEBBASND-DEBBASIC(,14) Compute address of the ->
device area
L 15,DEBUCBAD-DEBDASD(,14) Load address of the UCB
N 15,=A(X'FFFFFF') Isolate the 24-bit UCB address
MVC volser,UCBVOLI-UCBOB(15)
...
DCBD DSORG=QS,DEVD=DA
IEFUCBOB ,
IEZDEB ,
I had to do this by memory, I'm afraid. For some reason I can't get to a z/OS system to look at the macros.
Subject to the AMODE 24 issue, I see no reason what the 1996 code will break. However, why go to the UCB to get the volume? It's in the JFCB at JFCBVOLS