Examples
Example 2. VTOC OBTAIN
This example is a bit less trivial than the first. This routine, named obtain, executes the MVS OBTAIN routine in order to retrieve the format 1 and format 3 DSCBs for a data set and volume, specified as parameters to the routine. The format-1 DSCB contains space information for the first 3 extents, while the first format-3 can contain (up to) the next 13 extents for the data set on the specified volume. Using the field ds1lstar and the extent information allows for an approximate calculation of used and allocated pace for the data set. Details of the OBTAIN SVC can be found in z/OS DFSMSdfp Advanced Services© Chapter 1. Using the Volume Table of Contents. To use the OBTAIN routine the OBTAIN and CAMLST macros are coded.
The OBTAIN macro allows for more than one DSCB to be read at one invocation, with a maximum of 12 DSCBs. This number is supplied to the macro with the NUMBERDSCB parameter. Each returned DSCB entry requires 140 bytes, therefore the C program shown here defines a work area of 1680 bytes. The OBTAIN macro parameter EADSCB specifies whether a program supports data sets with format-8 and format-9 DSCBs, which can occur on extended address volumes, and is set to EADSCB=OK for this routine.
The signature line for this routine is:
extern int obtain(char *dsname, char *volume, struct format1 *_dscb)The struct that maps the DSCB, which is the output from this routine is not shown here. It was generated from the DSCB mapping macro IECSDSL1, using the IBM supplied program CCNEDSCT, which converts Assembler storage definitions into C structs.
The OBTAIN macro loads the address of the CAMLST parameter list into R1 and then invokes SVC 27. To do this in C, I coded the expanded macro statements as __asm statements. The input constraint "r"(&_work), tells the compiler to load a register with the address of the C variable _work. The clobber list specifies R1 not be used, since the OBTAIN routine will use it.
The second __asm statement saves the return code from the OBTAIN routine into the C variable rc, which is the returned value from the C routine.
int obtain(char *dsname, char *volume, struct format1 *_dscb)
{
int rc;
char workarea[1680];
struct camlist
{
unsigned char field1;
unsigned char flag1;
unsigned char flag2;
unsigned char flag3;
void *dsname;
void *volume;
void *workarea;
} ;
struct camlist _work;
memset(&_work, 0, sizeof(struct camlist));
memset(&workarea, 0, sizeof(workarea));
_work.field1 = 193;
_work.dsname = dsname;
_work.volume = volume;
_work.workarea = &workarea;
#ifdef __MVS__
__asm(" LR 1,%0 load parameter reg 1\n"
" OI 2(1),B'00001000' set obtain option flags off\n"
" MVI 3(1),12 set number of possible dscbs\n"
" SVC 27 issue OBTAIN SVC\n"
:
: "r"(&_work)
: "r1");
__asm(" ST 15,%0 "
: "=m"(rc)
:
: "r0", "r1", "r14", "r15");
#endif
memcpy(_dscb, _work.workarea, sizeof(workarea));
return rc;
}
The HLASM code produced from the compilation of the C source is shown below.
.* The HLASM GOFF option is needed to assemble this program
ACONTROL AFPR
FILESTAT CSECT
FILESTAT AMODE 31
FILESTAT RMODE ANY
SYSSTATE ARCHLVL=2
IEABRCX DEFINE
@@CCN@76 ALIAS C'obtain'
* #include "fileStat.h"
* #ifdef __MVS__
* #pragma export(obtain)
* #endif
*
* #ifndef __MVS__
* #include
* #endif
*
*
* extern int obtain(char *dsname, char *volume, struct format1 *_dscb)
J @@CCN@76
@@PFD@@ DC XL8'00C300C300D50000' Prefix Data Marker
DC CL8'20141024' Compiled Date YYYYMMDD
DC CL6'100352' Compiled Time HHMMSS
DC XL4'410D0000' Compiler Version
DC XL2'0000' Reserved
DC BL1'01000000' Flag Set 1
DC BL1'00000000' Flag Set 2
DC BL1'00000000' Flag Set 3
DC BL1'00000000' Flag Set 4
DC XL4'00000000' Reserved
ENTRY @@CCN@76
@@CCN@76 AMODE 31
DC XL8'00C300C300D50100' Function Entry Point Marker
DC A(@@FPB@1-*+8) Signed offset to FPB
DC XL4'00000000' Reserved
@@CCN@76 DS 0F
STM 14,3,12(13)
LR 15,13
L 13,8(,13)
ST 15,4(,13)
@@BGN@1 DS 0H
USING @@AUTO@1,13
LARL 3,@@LIT@1
USING @@LIT@1,3
ST 1,88(,13) #SR_PARM_1
* {
*
* int rc;
* char workarea[1680];
*
* struct camlist
* {
* unsigned char field1;
* unsigned char flag1;
* unsigned char flag2;
* unsigned char flag3;
* void *dsname;
* void *volume;
* void *workarea;
* } ;
*
* struct camlist _work;
* memset(&_work, 0, sizeof(struct camlist));
XC @81_work,@81_work
USING @@PARMD@1,1
L 15,@77dsname
* memset(&workarea, 0, sizeof(workarea));
LA 14,@83workarea
MVI 96(13),193
L 0,@78volume
XC 0(256,14),0(14)
ST 15,100(,13) _a1_d100_l4_
XC 256(256,14),256(14)
XC 512(256,14),512(14)
ST 14,108(,13) _a1_d108_l4_
XC 768(256,14),768(14)
XC 1024(256,14),1024(14)
*
* _work.field1 = 193;
* _work.dsname = dsname;
* _work.volume = volume;
ST 0,104(,13) _a1_d104_l4_
XC 1280(256,14),1280(14)
XC 1536(144,14),1536(14)
LA 2,@81_work
* _work.workarea = &workarea;
*
* #ifdef __MVS__
*
* __asm(" LR 1,%0 load parameter reg 1\n"
LR 1,2 load parameter reg 1
OI 2(1),B'00001000' set obtain option flags off
MVI 3(1),12 set number of possible dscbs
SVC 27 issue OBTAIN SVC
* " OI 2(1),B'00001000' set obtain option flags off\n"
* " MVI 3(1),12 set number of possible dscbs\n"
* " SVC 27 issue OBTAIN SVC\n"
* :
* : "r"(&_work)
* : "r1");
*
* __asm(" ST 15,%0 "
LA 2,@90rc
ST 15,0(2)
* : "=m"(rc)
* :
* : "r0", "r1", "r14", "r15");
* #endif
*
* memcpy(_dscb, _work.workarea, sizeof(workarea));
L 14,88(,13) #SR_PARM_1
L 15,108(,13) _a1_d108_l4_
DROP 1
USING @@PARMD@1,14
L 14,@79_dscb
MVC 0(256,14),0(15)
MVC 256(256,14),256(15)
MVC 512(256,14),512(15)
MVC 768(256,14),768(15)
MVC 1024(256,14),1024(15)
MVC 1280(256,14),1280(15)
MVC 1536(144,14),1536(15)
*
* return rc;
L 15,@90rc
* }
@1L27 DS 0H
DROP
L 13,4(,13)
L 14,12(,13)
LM 1,3,24(13)
BR 14
DS 0F
@@LIT@1 LTORG
@@FPB@ LOCTR
@@FPB@1 DS 0F Function Property Block
DC XL2'CCD5' Eyecatcher
DC BL2'1111000000000011' Saved GPR Mask
DC A(@@PFD@@-@@FPB@1) Signed Offset to Prefix Data
DC BL1'00000000' Flag Set 1
DC BL1'10000000' Flag Set 2
DC BL1'00000000' Flag Set 3
DC BL1'00000000' Flag Set 4
DC XL4'00000000' Reserved
DC XL4'00000000' Reserved
EJECT
@@AUTO@1 DSECT
DS 448F
ORG @@AUTO@1
#GPR_SA_1 DS 18F
DS F
ORG @@AUTO@1+92
@90rc DS F
ORG @@AUTO@1+112
@83workarea DS XL1680
ORG @@AUTO@1+96
@81_work DS XL16
ORG @@AUTO@1+88
#SR_PARM_1 DS XL4
@@PARMD@1 DSECT
DS XL12
ORG @@PARMD@1+0
@77dsname DS F
ORG @@PARMD@1+4
@78volume DS F
ORG @@PARMD@1+8
@79_dscb DS F
*
END ,(5694A01 ,1D00,14297)
References
- z/OS DFSMSdfp Advanced Services©
- z/OS Metal C Programming Guide and Reference
- z/OS XL C/C++ Language Reference
All references copyright© IBM Corporation.