svc99() — Access supervisor call
Standards
Standards / Extensions | C or C++ | Dependencies |
---|---|---|
Language Environment® | both |
Format
#include <stdio.h>
int svc99(__S99parms *string);
General description
- Dynamically allocate or deallocate a resource
- Dynamically concatenate or deconcatenate data sets
- Dynamically retrieve information on data sets
To avoid infringing on the user's name space, this nonstandard function has two names. One name is prefixed with two underscore characters, and one name is not. The name without the prefix underscore characters is exposed only when using the runtime library extensions.
The __S99parms structure must be in 31-bit addressable storage. A call to svc99() with 64-bit addressable storage will result in -1 return code.
The __S99TXTPP element needs to be a 32-bits wide pointer to 31-bit addressable storage containing an array of text unit pointers. Each of the text unit pointers must be a 32-bits wide pointer, each pointing to 31-bit addressable storage containing a text unit, or can be a NULL pointer. The last text unit pointer must have its high bit (traditional 31-bit amode high bit) turned on to denote the end of text units has been reached.
The __S99S99X element needs to be a 32-bits wide pointer to 31-bit addressable storage containing the __S99rbx structure, when needed. This is consistent with the __dyn_t structure element __rbx requirement outlined above.
The __S99parms
structure is defined in stdio.h
.
It has been changed to include the address of the Request Block Extension.
The Request Block Extension and the Error Message Parameter list can
be used to process the messages returned by SVC99 when an error occurs.
To use this feature, you must allocate and initialize these structures.
Field | Type | Value Stored |
---|---|---|
__S99RBLN | unsigned char | SVC99 length of request block |
__S99VERB | unsigned char | SVC99 verb code |
__S99FLAG1 | unsigned short | SVC99 Flags 1 field |
__S99ERROR | unsigned short | SVC99 error code field |
__S99INFO | unsigned short | SVC99 information code |
__S99TXTPP | void * __ptr32 | SVC99 pointer to a list of text unit pointers |
__S99S99X | void * __ptr32 | SVC99 pointer to the Request Extension Block |
__S99FLAG2 | unsigned int | SVC99 Flags 2 field for APF authorized programs |
Returned value
If the input pointer is NULL, svc99() returns 0 if running under CICS® and nonzero otherwise. The nonzero value indicates that svc99() is supported under the current operating system (that is, z/OS non-CICS). If the input is not NULL, svc99() returns -1 if running under CICS (to indicate an error), otherwise it returns a code that results from svc99().
If the input is not NULL, and svc99() is not supported on the system, it returns -1.
Example
/* CELEBS58
This example uses the svc99() function to dynamically allocate a data
set called USERID.EXAMPLE.
*/
#define MASK 0x80000000
#define _EXT
#include <stdio.h>
#include <string.h>
int main(void)
{
int rc;
struct __S99struc parmlist;
char *s[10] = { /* array of text pointers */
/* text units follow */
"\0\x02\0\x01\0\x0E""USERID.EXAMPLE", /* DSN=EXAMPLE */
"\0\x05\0\x01\0\x01\x02", /* DISP=(,CATLG) */
"\0\x07\0\0", /* SPACE=(TRK,.. */
"\0\x0A\0\x01\0\x03\0\0\x14", /* primary=20 */
"\0\x0B\0\x01\0\x03\0\0\x01", /* secondary=1 */
"\0\x15\0\x01\0\x05SYSDA", /* UNIT=SYSDA */
"\0\x30\0\x01\0\x02\0\x50", /* BLKSIZE=80 */
"\0\x3C\0\x01\0\x02\x40\0", /* DSORG=PS */
"\0\x42\0\x01\0\x02\0\x50", /* LRECL=80 */
"\0\x49\0\x01\0\x01\x80"}; /* RECFM=F */
memset(&parmlist, 0, sizeof(parmlist));
parmlist.__S99RBLN = 20;
parmlist.__S99VERB = 1; /* verb for dsname allocation */
parmlist.__S99FLAG1 = 0x4000; /* do not use existing allocation */
parmlist.__S99TXTPP = s; /* pointer to pointer to text units */
s[9] = (char *)((long unsigned) (s[9]) | MASK);
rc = svc99(&parmlist);
if (rc != 0)
printf(" Error code = %d Information code = %d\n",
parmlist.__S99ERROR, parmlist.__S99INFO);
}
If your user ID starts with one of the letters A-F, you must add two double quotation marks (") before the user ID so that the first letter of the user ID is interpreted as a character rather than as a hexadecimal digit.
The preceding example can be made more readable by using symbolic
names and data structures as demonstrated in the example below. The
members IEFZB4DB
, IEFZB4D0
and IEFZB4D2
of SYS1.MACLIB
contain
symbolic names that will be familiar to most assembler language programmers.
#include <stdio.h>
#include <string.h>
#define MASK 0x80000000
#define CHAR_BIT 4
/* Defines one text unit with an integer of size 'bytes' */
#define __S99TUNIT_INT(bytes) struct {
short unsigned __S99TUKEY; /* KEY */
short unsigned __S99TUNUM; /* NO. OF LENGTH+PARM ENTRIES */
struct { /* TEXT ENTRY OF LENGTH+PARM */
short unsigned __S99TULNG; /* LENGTH OF 1ST (ONLY) PARM */
unsigned int __S99TUPAR : /* PARAMETER */
(bytes) * CHAR_BIT;
} __S99TUENT;
}
/* initialize by: __S99TUNUM = 1; */
/* __S99TUENT.__S99TULNG = <bytes>; */
/* __S99TUENT.__S99TUPAR = <value>; */
#define __DALPRIME 0x000A /*PRIMARY SPACE QUANTITY */
static const __S99TUNIT_INT(3) primary = {__DALPRIME, 1, 3, 20};
int main(void)
{
int rc;
struct __S99struc parmlist;
memset(&parmlist, 0, sizeof(parmlist));
void *s[10] = { /* array of text pointers */
/* text units follow */
. , /* DSN=EXAMPLE */
. , /* DISP=(,CATLG)*/
. , /* SPACE=(TRK,..*/
&primary, /* primary=20 */
. , /* secondary=1 */
. , /* UNIT=SYSDA */
. , /* BLKSIZE=80 */
. , /* DSORG=PS */
. , /* LRECL=80 */
. }; /* RECFM=F */
parmlist.__S99RBLN = 20;
parmlist.__S99VERB = 01; /* verb for dsname allocation */
parmlist.__S99FLAG1 = 0x4000; /* do not use existing allocation */
parmlist.__S99TXTPP = s; /* pointer to pointer to text units */
s[9] = (char *)((long unsigned) (s[9]) │ MASK);
rc = svc99(&parmlist);
if (rc != 0)
printf(" Error code = %d Information code = %d\n",
parmlist.__S99ERROR, parmlist.__S99INFO);
}