Introduction to Unix Callable Services
I start a small series of articles regarding Unix System Services (USS) and how to access Unix properties from an assembler program, either started from JCL or in the Unix shell. I start by showing how to access services and later the File System (zFS).
If you have no idea what I am talking about, please read the article linked to below. Even if you know something about USS you might benefit from reading it:
Crossing the border
Programming between native z/OS and zOS UNIX Systems Services
|
I have borrowed some of the examples in the article.
Calling the services
In the Unix society the programming language C is what assembler is for z/OS. So it can be no surprise that z/OS offers all services in Unix C to assembler. These services are the same modules that is used by C. There are (at least) three ways to find these Callable Services:
- by static linking each module into your load module and CALL it
- by loading the module into storage and CALL it
- by finding the address of the preloaded module in a control block and CALL it
I will definitely recommend the latter and that is what my examples will do.
L R15,16 R15 -> Common Vector Table
L R15,CVTCSRT-CVT(15) R15 -> CSRTABLE
L R15,24(R15) R15 -> CSR slot
L R15,276(R15) R15 = Address of service svc
BALR 14,15
|
There is a table of addresses of each module. At offset 276 is the address of “getpid” (get process id).
Parameters
You pass parameters in a list of addresses to the module exactly as you would to any other module.
PARM DS F
PROCESSID DS F
...
...
LA R15,PROCESSID
ST R15,PARM
OI PARM,X'80'
LA 1,PARM
|
This example passes only one parameter, PROCESSID but we will later handle several parameters
MACRO to USS Callable Service
I am a macro guy so I have of course made a macro to facilitate the call of a Unix Callable Service. It is supposed to be extended with offsets to more Unix Callable Services.
MACRO
.***************************************************
.**
.** Macro USSSERV - Call USS Callable Services **
.**
.***************************************************
&LABEL USSSERV &SERVICE,&PARMS
GBLC &PARM_LABEL
.***************************************************
.** Storage definitions **
.***************************************************
AIF ('&SERVICE' EQ 'PARM').PARM
AIF ('&SERVICE' EQ 'DSECT').DSECT
.***************************************************
.** Callable Services **
.***************************************************
AIF ('&SERVICE' EQ 'GETPID').GETPID
AIF ('&SERVICE' EQ 'OPEN').OPEN
AIF ('&SERVICE' EQ 'CLOSE').CLOSE
AIF ('&SERVICE' EQ 'READ').READ
MNOTE 8,'Wrong SERVICE'
AGO .END
.***************************************************
.** Define parm list **
.***************************************************
.PARM ANOP
&LABEL DS &PARMS.F
&PARM_LABEL SETC '&LABEL'
&PARM_LABEL._LENGTH EQU *-&LABEL
AGO .END
.***************************************************
.** Define DSECT for the BPX-services **
.***************************************************
.DSECT ANOP
PUSH PRINT
PRINT NOGEN
CVT DSECT=YES
BPXYMODE LIST=NO
BPXYOPNF LIST=NO
POP PRINT
AGO .END
.***************************************************
.** Get Process id **
.***************************************************
.GETPID ANOP
&OFFSET SETC '276'
AGO .MAKECODE
.***************************************************
.** Open file **
.***************************************************
.OPEN ANOP
&OFFSET SETC '156' BPX1OPN
AGO .MAKECODE
.***************************************************
.** Read a file **
.***************************************************
.READ ANOP
&OFFSET SETC '176' BPX1RED
AGO .MAKECODE
.***************************************************
.** Close a file **
.***************************************************
.CLOSE ANOP
&OFFSET SETC '72' BPX1CLO
AGO .MAKECODE
.***************************************************
.** Make the code to set the parm and the address **
.** of the Service **
.***************************************************
.MAKECODE ANOP
&N SETA N'&PARMS
&I SETA 0
.LOOP_PARMS ANOP
LA R15,&PARMS(&I+1)
ST R15,&PARM_LABEL+(4*&I)
&I SETA &I+1
AIF (&I LT &N).LOOP_PARMS
OI &PARM_LABEL+(4*(&N-1)),X'80'
.**************************************
.** Find the Callable Service **
.**************************************
L 15,16 R15 -> Common Vector Table
L 15,CVTCSRT-CVT(15) R15 -> CSRTABLE
L 15,24(R15) R15 -> CSR slot
L 15,&OFFSET.(15) R15 = Address of service svc
LA 1,&PARM_LABEL
BALR 14,15 .***************************************************
.** End-Of-Macro **
.***************************************************
.END ANOP
MEND
|
The macro has a “Service” called “CVTDSECT”. That must be placed outside any DSECT or CSECT. It is used to calculate an offset.
I will change this macro as I need more services and parameters.
Exampel program
PROGRAM EQU
*************************
WS PROGRAM STORAGE
WSEC DS CL16
PARM DS f
PROCESSID DS F
PID_PACKED DS PL8
PID_CHAR DS CL16
WTO DS 0f
WTOLGD DS H
WTOTEXT DS CL70
PROGRAM STORAGE
USSSERV CSVDSECT
*************************
PGM12 PROGRAM START
MVC WSEC,=CL(L'WSEC)'PGM12-WS'
USSSERV GETPID,PROCESSID
l R1,processid
CVD R1,PID_PACKED
MVC PID_CHAR,EDIT_FIELD
ED PID_CHAR,PID_PACKED
MVC WTOTEXT(10),=C'Processid:'
MVC WTOTEXT+10(l'PID_CHAR),PID_CHAR
MVC WTOLGD,=Y(l'WTOTEXT)
WTO TEXT=WTO,ROUTCDE=11
B RETURN
EDIT_FIELD DC C' ',(L'PID_CHAR-1)X'20'
NO_STORAGE_OBTAINED DS 0H
WTO 'PGM12 - Return med fejl',ROUTCDE=11
L R13,SAVEAREA+4
LM R14,R12,12(R13)
RETURN RC=8
*************************
* End of program
*************************
RETURN PROGRAM END
LTORG
END
|
Manual
z/OS V1R13.0 UNIX System Services Programming:Assembler Callable Services Reference - SA22-7803-14
List of offsets on page 1011 (Table 24. System control offsets to callable services)