osdynalloc
, is provided to interface to the MVS dynamic
allocation facility. This function can be used to allocate a data
set to a DDname, or to obtain information about existing allocations.
These functions are characterized as low level because they use the
MVS access method and supervisor services directly.
This chapter covers these low-level I/O functions. Note that these functions are not portable. Though these functions are intended for use under MVS, they should function correctly under CMS, subject to the limitations of CMS BSAM simulation. MVS low-level I/O can be used in the minimal SPE environment as well as with the full run-time library.
MVS low-level I/O is supplied in source form, so it can be easily modified to support other access methods or unusual file types. See members L$UBSAM, L$UDCB, and L$UOSIO in SASC.SOURCE (MVS) or LSU MACLIB (CMS).
The direct BSAM interface functions are as follows:
osbclose
osbdcb
osbldl
osbopen
osbopenj
oscheck
osfind
osfindc
osnote
ospoint
osread
ostclose
osstow
oswrite
The record-oriented interface functions are as follows:
osclose
osopen
.
osdcb
osflush
osget
osopen
osopenj
osseek
osput
ostell
The functions osfind
, ostclose
, and osstow
from the
BSAM interface can be used with files opened using the record
interface. You can also initialize a DCB using osdcb
and then
process it entirely with the direct BSAM interface.
The IBM publication MVS/DFP Using Data Sets (SC26-4749)
contains additional information about BSAM.
There is only one dynamic allocation interface function,
osdynalloc
. This function offers a number of different
subfunctions, including allocation, deallocation, concatenation,
and retrieval of attributes of data sets. The IBM publication
MVS/ESA Application Development Guide: Authorized Assembler Language Programs
(GC28-1645)
provides additional information about
dynamic allocation.
DCBs and DCB Exit Routines
The BSAM interfaces require that you allocate and initialize a DCB
(data control block) using osbdcb
or osdcb
. The address of
the DCB is then passed to the other I/O routines as an argument. Many
BSAM functions require you to extract or modify data in the DCB. The
header file <osio.h>
contains a C structure definition for the DCB
defining all necessary fields and constants.
Advanced use of BSAM in assembler frequently requires the coding of DCB exit routines, which are routines called by BSAM during processing of the DCB. (For instance, the SYNAD exit is called during processing of I/O errors.) Both BSAM interfaces enable you to write DCB exit routines in C. When you do this, the library takes care of linkage details for you so that the exit routine is called as a normal C function and the full facilities of the SAS/C Library can be used. (For instance, an assembler DCB exit routine is always entered in 24-bit addressing mode. However, before calling a C exit routine, the library switches back to 31-bit addressing mode, for a program that runs in that mode, so that data allocated above the 16-megabyte line can be accessed.)
When you use BSAM in assembler, you specify DCB exits by creating an
exit list. Each entry in the list contains an exit type code and
an entry address. The list of exits is then accessed via the DCBEXLST
field of the DCB. When you use the SAS/C BSAM interface, the process
is similar but not identical. You create a list of exits in which each
entry contains an exit type code and a function address. (The C exit
list format is not the same as the assembler format because of the need
to support 31-bit addressing.) The list of exits is passed to osbdcb
or osdcb
as an argument. This routine then transforms the C
exit list into a similar assembler exit list, modifies the DCB, and
actually performs the OPEN. (Note that some entries in an exit list
are used as data addresses, such as a JFCB buffer address, rather than
as function addresses. A different field name is used for storing a
data pointer rather than a function pointer in an exit list.
When an exit routine is entered in assembler, parameters such as the
address of the DCB or an I/O status block are passed in registers 0 and
1. When a corresponding C exit routine is called, it is passed two
parameters, the first of which is the value that would be passed to the
assembler exit in register 1, and the second is the register 0
contents. All exit functions should be declared as returning int
,
and the value returned is returned to BSAM in register 15.
Note that a C SYNAD exit requires slightly different linkage. When a C SYNAD exit is called, the library issues the SYNADAF macro before passing control to the exit routine. The address of the message constructed by SYNADAF is passed as the first argument, and the address of the DECB (data event control block) is the second argument. If the DCB address is required, it can be extracted from the SYNADAF message.
The BSAM interface supports escape from a DCB exit routine using the
longjmp
function. However, control is returned to data management
with a value of 0
in register 15 before the longjmp
is allowed to
complete.
Note:
When a DCB exit routine is running, use of some system
services may cause task interlocks or ABENDs. Dynamic allocation and
open are examples of such services. This means that you should not
open a file in a routine called from a DCB exit. Also, be careful
performing I/O to stdin
, stdout
, or stderr
from a DCB
exit because an operating system OPEN will be
issued for these files if they have not been previously used.
Finally, when debugging a DCB exit with the
source level debugger, use the auto nolist
command to prevent debugger
access to the program source because the debugger uses dynamic
allocation to gain access to the program source.
Direct BSAM Interface Functions
Descriptions of each direct BSAM interface function follow.
#include <osio.h> DCB_t *osbdcb(exit_t exit_list); int osbopen(DCB_t *dcbp, const char *option); int osbopenj(DCB_t *dcbp, const char *option); int osbldl(DCB_t *dcbp, void *bldl_data); int osfind(DCB_t *dcbp, const char *member); int osfindc(DCB_t *dcbp, unsigned TTRK); void osbclose(DCB_t *dcbp, const char *option, int free); void ostclose(DCB_t *dcbp, const char *option); void osread(DECB_t decb, DCB_t *dcbp, void *buf, int length); void oswrite(DECB_t decb, DCB_t *dcbp, const void *buf, int length); int oscheck(DECB_t decb); unsigned osnote(DCB_t *dcbp); void ospoint(DCB_t *dcbp, unsigned blkaddr); int osstow(DCB_t *dcbp, const void *data, char type);
osbdcb
function builds and initializes a BSAM DCB, and returns
its address. The DCB address is then passed to the other routines to
control their operation. The DCB includes a 16-byte extension of which
12 bytes are used by the library and 4 bytes are available for your
use. (The name of the available field is DCBUSER.)
The argument to osbdcb
, exit_list
, is of type exit_t []
, and the return value is of type DCB_t *
.
Both of these types are defined in <osio.h>
. The definition of
exit_t
is as follows:
enum _e_exit {INACTIVE, INHDR, OUTHDR, INTLR, OUTTLR, OPEN, EOV, JFCB, USER_TOTAL=10, BLK_COUNT, DEFER_INTLR, DEFER_NONSTD_INTLR, FCB=16, ABEND, JFCBE=21, TAPE_MOUNT=23, SECURITY=24, LAST=128, SYNAD=256} ; /* exit type */ typedef __remote int (*_e_exit_fp)(void *, void *); /* exit function type */ typedef struct _e_exit_list { /* exit list entry definition */ unsigned exit_code; /* actually an enum _e_exit, */ /* possibly with LAST bit set */ union { _e_exit_fp exit_addr; /* exit function address */ void *area_addr; /* pseudo-exit (e.g., JFCB) address*/ }; } exit_t;Consult IBM publication MVS/DFP Using Data Sets (SC26-4749) for information on the functions of the individual exits described by the codes above. Note that the last entry in the list must have the LAST bit set in its
exit_code
field. If only the LAST bit is set, the entry is
considered inactive and ignored. You should specify an exit_code
similar to (LAST | ABEND) if the last entry actually defines an exit.
If you need to pass a data address in the exit list, use the field name
data_addr
rather than area_addr
to store it. Note that data
addresses cannot be supplied as initial values for an exit list.
Note that the exit_list
is converted by osbdcb
into an
assembler format exit list whose address is stored in DCBEXLST of the
returned DCB. Modifications to the list passed to osbdcb
after
the call do not update the DCBEXLST value and, therefore, have no
effect. Also note that if no exits are required, an argument of 0
should be passed to osbdcb
.
The definition of DCB_t
is too long to reprint here. It was
generated from the DFP version 2 IHADCB DSECT using the DSECT2C
utility. In addition to all the usual DCB symbols, the symbol DCBLRC_X
has been defined as the DCBLRECL code stored to indicate LRECL=X.
Note:
The definition of DCB_t
requires the use of the compiler option
bitfield
, with a default allocation unit of char
, in
order to compile correctly.
osfind
The osfind
function is called to issue the FIND macro for a DCB,
to position the file to the start of a member. The member name is
passed as a null-terminated string, in either upper- or lowercase. The
value returned by osfind
is the same as the return code from the
FIND macro.
osbldl
The osbldl
function can be used to locate PDS
members more efficiently than with the osfind
function.
osbldl
can look up more than one member at once.
The osbldl
function is called to issue the MVS BLDL SVC to locate
one or more members of a PDS. The dcbp
argument is a pointer to
the DCB for the PDS. The bldl_data
argument is an area of storage
defining the number and names of the members to be located. See IBM's
DFP Macro Instructions for Data Sets for information on
the format of the BLDL input data. bldl_data
should be allocated
below the 16 megabyte line.
The value returned by osbldl
is the R15
value returned by the
BLDL SVC.
If you are
using the record-oriented BSAM interface, you may need to use
osflush
before calling osfind
to quiesce any outstanding I/O.
osbopen, osbopenj
The functions osbopen
and osbopenj
are called to open a
DCB
using either the normal OPEN macro or an OPEN with TYPE=J. The option
argument is a character string that should specify a valid
OPEN macro keyword such as "input", "inout", or "updat". The string may
be either upper- or lowercase. An invalid option
is treated as
"input". osbopen
and osbopenj
return 0
if successful or
nonzero if unsuccessful.
osfindc
The osfindc
function can be used to locate PDS
members more efficiently than with the osfind
function.
osfindc
can locate a member without having to search the PDS directory.
The osfindc
function is called to position to a PDS member using
data returned by the osbldl
function by issuing the MVS FIND C
macro. The dcbp
argument is a pointer to the DCB for the PDS.
The
TTRK
argument is the TTRK value returned by osbldl
for the
required member.
The osfindc
function returns the value stored in register 15
by the FIND C macro.
Using the record-oriented BSAM interface, you may need to use
osflush
before calling osfind
to quiesce any outstanding I/O.
osbclose, ostclose
The functions osbclose
and ostclose
are called to close a
BSAM DCB permanently (osbclose
) or temporarily (ostclose
).
The option
argument is a character string that should specify
a valid CLOSE macro keyword such as "leave" or "reread". The string
may be either upper- or lowercase. An invalid option
is treated
as "disp". The free
argument of osbclose
specifies whether
the DCB should be freed after the close: 0
leaves the DCB allocated and
nonzero frees it. If the DCB is freed, a FREEPOOL macro also is issued
to release any buffers allocated by OPEN. Note that osbclose
can
process a DCB that has already been closed or never opened. This is
useful for freeing a DCB that could not be opened.
Note:
Files processed via MVS low-level I/O are not closed
automatically by the library at program termination. This can cause a
C03 ABEND for a program that opens one or more DCBs and then calls exit
. You can use the atexit
library function to define a
cleanup routine that closes all open DCBs to avoid this problem.
osread, oswrite
The functions osread
and oswrite
are called to read or write
a block of data using a BSAM DCB. You must pass a DECB to control the
operation. (This control block is later passed to oscheck
to wait
for the I/O to complete.) The data type DECB_t
is defined by the
library (as unsigned [5]
) as the type of a
DECB. You must also pass osread
and oswrite
the address of
the buffer containing the data to be read or written and the length to
read or write. The length is meaningful only for RECFM=U records; you
can specify a length of 0
to use the value in DCBBLKSI. (A length of 0
is equivalent to the assembler specification 'S'.) No value is returned
by osread
or oswrite
because you need to call oscheck
to
determine whether an I/O operation was successful. Note that the
buffer passed to osread
or oswrite
must be allocated below
the 16-megabyte line in MVS/XA. One way to assure this is to define
the buffer areas as auto
because auto
variables always are
allocated below the line.
oscheck
oscheck
is called to wait for a READ or WRITE to complete and to
determine whether the I/O was successful. The argument to oscheck
is the address of the DECB for the operation to check. The value
returned by oscheck
is 0
for a successful read or write,
-1
if the
end of the file was detected, and -2
if an I/O error occurred (that is,
if the SYNAD exit was called) or if some other condition occurred that
caused the DCB to be closed. Note that information on the length of an
input block is not returned. See IBM's Using Data Sets
for information on determining this for various record formats.
osnote, ospoint
The osnote
and ospoint
functions are used to query or modify
the file position for a BSAM file. For a sequential file, you must set
the DCBMRPT1 and DCBMRPT2 bits in the DCB before the file is opened to
use these functions. osnote
returns the value returned by the
NOTE macro in register 1. This is a block number for a tape file or a
TTRz value for a disk file.
osstow
The osstow
function is used to update a PDS directory by issuing
the STOW macro. The arguments to osstow
must be located in
storage below the 16Mb line. To ensure this, the arguments should be
defined as auto variables or if they are external or static variables
the RENT compiler option should be specified. The type
argument
is a single character specifying the operation to be performed, such as
'A' to add a directory entry or 'D' to delete one. The format of the
data
argument varies according to the type of request, as
described in IBM's Using Data Sets. Note that a member
name contained in the data
area should not be null-terminated and
will not be translated to uppercase. The return value from osstow
is the same as the register 15 return code from the STOW
macro.
osbdcb
, each function invokes the
associated BSAM macro. Refer to IBM's Using Data Sets and
the Macro Instructions for Data Sets (IBM publication
SC26-4747) for more information on individual macros.
Note that this example uses several other unique features of the compiler, such as the inline SVC interface and anonymous unions.
#include <osio.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <getmain.h> static int abend_exit(void *reg1, void *reg0); /* Register 1 argument to DCB ABEND exit. */ struct abend_info { unsigned abend_code: 12; unsigned :4; unsigned char return_code; union { struct { unsigned :4; unsigned recover: 1; unsigned ignore: 1; unsigned delay: 1; unsigned :1; }ok_to; char action; }; DCB_t *dcbp; void *O_C_EOV_workarea; void *recovery_work_area; }; int full; /* Set to 1 if "file full" ABEND occurs. */ main() { DCB_t *input, *output; exit_t out_exlst[1] = {LAST | ABEND, &abend_exit }; DECB_t input_DECB, output_DECB; char *buf; int count = 0; int err; input = osbdcb(0); memcpy(input->DCBDDNAM, "INPUT ", 8); if (osbopen(input, "input")) { puts("Input open failed."); exit(16); } output = osbdcb(out_exlst); /* Copy output file characteristics from input. */ output->DCBRECFM = input->DCBRECFM; output->DCBLRECL = input->DCBLRECL; output->DCBBLKSI = input->DCBBLKSI; memcpy(output->DCBDDNAM, "OUTPUT ", 8); if (osbopen(output, "output")) { puts("Output open failed."); osbclose(input, "", 1); exit(16); } buf = (char *) GETMAIN_U(input->DCBBLKSI, 0, LOC_BELOW); /* Allocate buffer below the 16 megabyte line. */ for (;;) { osread(input_DECB, input, buf, 0); if ((err = oscheck(input_DECB)) != 0) { if (err != -1) puts("Input error."); break; } oswrite(output_DECB, output, buf, 0); if (oscheck(output_DECB) != 0) { if (full) puts("Output file full."); else puts("Output error."); break; } ++count; } printf("%d blocks copied.", count); FREEMAIN(buf, input->DCBBLKSI, 0, UNCOND); osbclose(output, "", 1); osbclose(input, "", 1); return 0; } /* reg0 is undefined and unused for this exit. */ static int abend_exit(void *reg1, void *reg0) { struct abend_info *info; info = (struct abend_info *) reg1; if ((info->abend_code == 0xb37 || info->abend_code == 0xd37 || info->abend_code == 0xe37) && info->ok_to.ignore) /* if ignorable file full condition */ { full = 1; info->action = 4; /* Tell BSAM to ignore ABEND. */ } else info->action = 0; /* Let any other ABEND proceed. */ return 0; }
QSAM features supported by the BSAM record interface include the following:
Differences between QSAM and the BSAM record interface include the following:
osfind
, osstow
, and
ostclose
to perform member-by-member PDS processing.
osseek
and ostell
routines allow a file to be
repositioned, which QSAM does not support.
The BSAM record interface also includes an osdcb
routine, which
can be used to define a DCB more conveniently than osbdcb
by using
a string of keyword parameters similar to the operands of the assembler
DCB macro. Although this interface is more convenient than
osbdcb
, additional processing is required to parse the keyword string. This
processing can be avoided by using osbdcb
and explicit code to
modify the DCB after it is allocated.
Controlling Buffering Using the Record Interface
The two DCB parameters that control buffering and overlapping of I/O
operations are BUFNO and NCP. If these are not specified by the user
when a file is opened, default values are assumed. Following are the
four different styles of buffering supported:
=1
and NCP=1
osseek
heavily.
=2
and NCP=1
osseek
and ostell
.
osseek
and ostell
are difficult or
impossible to use.
osseek
and ostell
can be used only if n is 1
.
osseek
and ostell
are similar to the standard SAS/C Library's
fseek
and ftell
functions. Unlike osnote
and
ospoint
, they use position indicators (of type ospos_t
) that identify a
particular record, rather than a particular block, of the file. As
part of its processing, ostell
calls osnote
to issue the NOTE
macro, and, similarly, osseek
calls ospoint
to issue the
POINT macro.
Unfortunately, a BSAM restriction requires that no I/O operations be
active when a NOTE or POINT is issued. This means that when ostell
or
osseek
is called, all reads or writes have to be checked, and
the advantages of overlapping I/O are lost. There is another, more
subtle problem as well.
Suppose the program has just called osget
to obtain a record and
now wants to call ostell
to find the position of the record.
osget
may have started to read one or more additional blocks. After
these read operations have been checked, a call to osnote
returns
the address of the last block read, which is not the same as the
address of the block containing the record most recently passed to the
program, the one whose address was requested. This problem means that
ostell
cannot usually be used meaningfully if the NCP value is
greater than 1
.
To allow the use of ostell
with BUFNO=2
, which allows I/O to
overlap with processing, the record interface supports a special mode
of operation called "autonote" mode. In this mode, after every block
is read or written, the library calls osnote
and saves the block
address for later use when the program calls ostell
. Note that
this requires that a NOTE be issued for every block, whether or not the
block address is required. For this reason, autonote mode should be
used only for applications in which the record address is used
frequently or in which the efficiency gains from double buffering
outweigh the loss from overuse of NOTE.
Autonote mode is set via an argument to osopen
and cannot be
changed once a DCB is opened.
Handling Spanned Records
The BSAM record interface mode is locate on input and move on
output. That is, the input routine stores a pointer to the input data
(within the BSAM buffer), and the output routine copies data to the
BSAM buffer. Spanned records on input are difficult to deal with in
locate mode because of the need to allocate a buffer to hold an entire
record, when the length of the record is unknown, until all segments
have been read. To bypass this problem, the SAS/C record interface is
segment-oriented rather than record-oriented for spanned records. If
segment consolidation is required, it can be performed by the
application program, which frequently has information unavailable to
the library about expected record lengths.
When the osget
routine is called, it stores the address and length
of the input record for nonspanned records. For spanned records, it
stores the segment address and length. If the segment is the last (or
only) segment of a record, the length is stored normally; for other
segments, the negative of the length is stored. An application that
needs to process an entire record at a time can call osget
to read
a segment at a time, stopping when a positive length is returned,
indicating the end of the record.
Processing of spanned records is similar on output. When osput
is
called, one argument is the length of the record to write. If the
length is negative, this indicates that the data are a record segment
and that additional segments are to be expected. The final segment is
indicated via a positive length. When record segments are passed to
osput
, the segments do not need to be physical segments because
osput
reblocks and resegments as necessary to match the output
file attributes. This enables records to be copied easily from one
record format to another without having to code elaborate logic to
despan and respan records.
Processing Concatenations with Unlike Attributes
One reason for using a low-level I/O interface as opposed to a
high-level interface such as standard C I/O is the ability to process
concatenated files with different attributes, such as a tape file
concatenated to a disk file or several files with different record
lengths. Processing like this is easy with the direct BSAM interface.
It is also supported via the record interface, but a little more work
is necessary to enable the interface to rebuild its buffer pool and
restart I/O when processing switches from one file to the next.
A brief summary of how to process unlike concatenations follows; for a more detailed description, see IBM publication MVS/DFP Using Data Sets (SC26-4749).
A program that supports concatenation of unlike data sets in assembler sets the DCBOFPPC bit of the DCBOFLGS field of the DCB. When the end of one of the concatenated data sets is reached, BSAM closes and reopens the DCB and frees and reallocates buffers for the file. Each time the DCB is closed and reopened, the DCB open exit is called by BSAM to inform the program that the file attributes may have changed and to give the program an opportunity to extract the new attributes from the DCB.
When the C record interface is used, the same DCB bit is used to
request unlike concatenation support from BSAM. You must provide a C
open exit, and the open exit must call the osflush
routine to
inform the record interface that the buffer pool has been freed and
reallocated. Also, you must specify NCP=1
to allow the library to
successfully restart I/O interrupted by the end of a concatenated
file.
BSAM Record-Oriented Interface Functions
Descriptions of each
BSAM record-oriented interface function
follow.
#include <osio.h> DCB_t *osdcb(const char *ddn, const char *keywords, exit_t exit_list, char **errp); int osopen(DCB_t *dcbp, const char *option, int autonote); int osopenj(DCB_t *dcbp, const char *option, int autonote); int osclose(DCB_t *dcbp, const char *option); int osget(DCB_t *dcbp, void **bufp, int *lenp); int osput(DCB_t *dcbp, const void *buf, int len); int osflush(DCB_t *dcbp, int func); int ostell(DCB_t *dcbp, ospos_t *posp); int osseek(DCB_t *dcbp, ospos_t pos);
osdcb
function builds and initializes a BSAM DCB and returns
its address. It is somewhat easier to use in complicated applications
than osbdcb
but has more overhead. Either osdcb
or osbdcb
can be used to build a DCB to be processed by either BSAM interface.
As with the DCB built by osbdcb
, the DCB includes a 16-byte
extension area for library and user use.
The ddn
argument to osdcb
is the DDname of the file to open.
The DDname should be null-terminated and can be in either upper- or
lowercase. A ddn
value of 0
can be specified if the DDname is not
known when the DCB is built. (In this case, the DDname must be stored
in the DCBDDNAM field by the program before the DCB is opened.)
The keywords
argument to osdcb
is a null-terminated string
containing DCB macro keywords, such as "dsorg=po,bufno=5". The
supported keywords are DSORG, RECFM, LRECL, BLKSIZE, OPTCD, NCP and
BUFNO. Keywords and their values can be specified in either upper- or
lowercase. If several keywords are specified, they can be separated by
blanks or commas.
The exit_list
argument of osdcb
is the same in all respects
as the exit_list
argument of osbdcb
.
See the description of
that function for details.
The errp
argument of osdcb
is used to control the processing
of errors in the keywords
string. If errp
is 0
and there is
an error in the keywords
string, a library warning message is
written to stderr
. If errp
is not 0
, it should address a
char *
variable, in which is stored the address of the invalid
keyword. This pointer can be used by the program to send a diagnostic
or correct the error.
osdcb
returns the address of the new DCB or 0
if no DCB was
created because of an error in the keywords
string.
osopen, osopenj
osopen
and osopenj
open a BSAM DCB for record-oriented access
using a normal OPEN macro or an OPEN TYPE=J respectively. The option
argument is a character string that should specify a valid
OPEN macro keyword such as "input", "inout" or "updat". The string can
be either upper- or lowercase. An invalid option
is treated as
"input". The autonote
argument is an integer specifying whether
the NOTE macro should be issued automatically after a READ or WRITE. A
value of 0
means that NOTE is not issued automatically, and a nonzero
argument means it is issued automatically. See Using osseek and ostell
for more information on autonote
.
When you use the record interface, RECFM=D data sets can be processed only with BUFOFF=L. (You do not need to set this option yourself; it is set automatically by the library.)
osopen
and osopenj
return 0
if successful or nonzero if
unsuccessful.
osclose
osclose
is called to close and free a DCB opened using osopen
or osopenj
. All buffers also are freed at the same time. The
option
argument is a character string that should specify a valid
CLOSE macro keyword such as "leave" or "reread". The string can be
either upper- or lowercase. An invalid option
is treated as
"disp". osclose
returns 0
if the DCB is closed successfully or
nonzero if any problems occur. Even if the return code is nonzero, the
DCB will have been freed. (A nonzero return code generally indicates a
problem
flushing buffers.) Note that osclose
can be used to free
the storage for a DCB that failed to open.
osget
The osget
function is called to read a record or record segment
and return its address and length. The bufp
argument addresses a
void *
variable in which the address of the record or record
segment will be stored. The value stored always addresses the data,
rather than the record prefix for V-format data. The lenp
argument addresses an int
variable in which to store the record or
segment length. For a spanned data set, the negative of the segment
length is stored except for the last or only segment of a record.
The return value from osget
is 0
for normal completion,
-1
for the
end of the file, or -2
for some other error. See oscheck
for more
details on the return code meaning.
osput
The osput
function is called to write a record or record segment.
The buf
argument is a void *
pointer addressing the record or
record segment to be written. The record should contain only data; any
record prefix needed is built by the library. The len
argument is
the length of the record or record segment to be written. For a
spanned record segment, len
should be positive for the last (or
only) segment of a record or, in any other case, the negative of the
segment length. If the record length does not match the DCB LRECL
specification, the record is padded with nulls or truncated. (This is
not considered an error.) A length of 0
can be used to terminate a
spanned record without adding any additional data.
The return value from osput
is 0
in the normal case, -2
if an I/O
error occurred, or -3
if osput
was called for a file opened for
UPDAT to write more bytes than were returned by the previous
osget
.
osflush
The osflush
function is called to terminate all I/O to
a DCB so the DCB can be modified safely. For instance, you should call
osflush
for a DCB before you issue the BSP SVC to backspace the
file. The func
argument to osflush
can take on one of four
values: QUIESCE
, REPOS
,
SYNCH
, or CONCAT
. These macros are defined in
<osio.h>
.
A func
value of QUIESCE
to osflush
informs the library that
the
position of the file will not be changed by processing after
osflush
completes. This enables the library to retain any
blocks that are
already read at the time osflush
is called.
A func
value of REPOS
to osflush
informs the
library
that the
position of the file may change, or that for some other reason, all
information about current file contents retained by the library should
be purged. Specifying REPOS unnecessarily causes additional library
processing the next time osget
or osput
is called for the DCB.
A func
value of SYNCH
to
osflush
specifies the same
processing as REPOS
, except that at the completion of all other
processing, a CLOSE TYPE=T is issued to the DCB, thus writing an
end-of-file mark and updating the directory for a PDS member.
A func
value of CONCAT
should be passed to osflush
only for a
call from an open exit for a concatenated input file. It handles
resynchronization and reallocation of buffers, and it should not be
used in any other circumstances.
The return value from osflush
is normally 0
, but can be a negative
value returned by oscheck
if errors occur during processing.
ostell
The ostell
function is called to store the current record address
for a BSAM file. The argument posp
is a pointer to an area of
type ospos_t
, in which the current record address should be
stored. The definition of ospos_t
is as follows:
typedef struct { unsigned _blkaddr; unsigned _recno; } ospos_t;The first field is the block address for the current block (as returned by
osnote
) and the second field is the current record number.
See Using osseek and ostell for more
information on this function.
ostell
returns 0
if successful or a nonzero value if it fails.
osseek
The osseek
function is called to reposition a BSAM file. The
argument pos
is a value of type ospos_t
defining the record
to seek. It is not necessary to call osflush
before calling
osseek
; osseek
does this automatically. See
Using osseek and ostell
for more information on this function.
osseek
returns 0
if successful or a nonzero value if it fails.
Note that an invalid argument to osseek
may cause an ABEND or
incorrect results later in processing rather than a nonzero return
code.
osstow
function to update the PDS
directory. The osflush(REPOS)
function is used to force all
output buffers to disk before updating the directory. Also, note
the use of an open exit to define default attributes for the
output data
set.
#include <osio.h> #include <stdio.h> static DCB_t *input, *output; static int open_exit(); main() { exit_t out_exlst[1] = {LAST | OPEN, &open_exit}; char *rec; int length; int err; int count = 0; struct { char name[8]; unsigned TTRC; } stow_data = {"MYMEMBER", 0}; input = osdcb("input", "recfm=fb,lrecl=80,bufno=10", 0, 0); if (osopen(input, "input", 0)) { puts("Input open failed."); exit(16); } output = osdcb("output", "recfm=fb,lrecl=80,bufno=10,dsorg=po", out_exlst, 0); if (osopen(output, "output", 0)) { puts("Output open failed."); exit(16); } for (;;) { err = osget(input, &rec, &length); if (err != 0) { if (err != -1) puts("Input error."); break; } err = osput(output, rec, length); if (err != 0) { puts("Output error."); break; } ++count; } if (err == 0) { /* if there were no errors */ err = osflush(output, REPOS); /* Flush output buffers. */ if (err == 0) /* Add member to PDS directory. */ err = osstow(output, &stow_data, 'A'); } if ((input->DCBRECFM & (DCBRECU | DCBRECSB)) == (DCBRECV | DCBRECSB)) /* if input file was spanned */ printf("%d segments copied.\n", count); else printf("%d records copied.\n", count); osclose(output, ""); osclose(input, ""); } static int open_exit(reg1, reg0) DCB_t *reg1; void *reg0; { /* If output file attributes unset, copy from input attributes. */ if (reg1->DCBRECFM == 0) { reg1->DCBRECFM = input->DCBRECFM;reg1->DCBLRECL = input->DCBLRECL; reg1->DCBBLKSI = input->DCBBLKSI; } return 0; }
#include <os.h> int osdynalloc(int action, char *keywords, char *libmsgbuf, ...);
osdynalloc
is used to invoke the MVS dynamic allocation SVC
(SVC 99). You can use osdynalloc
to allocate,
free, concatenate or
deconcatenate data sets, as well as
to return information about existing
allocations. MVS dynamic allocation is described in detail in the IBM
publication
MVS/ESA Application Development Guide: Authorized Assembler
Language Programs. Unless you are already familiar with>
dynamic allocation, you should read the sections of this book
discussing dynamic allocation to be aware of the restrictions and
other complexities of this powerful service.
The action
argument to osdynalloc
specifies the required
dynamic allocation action. The names of the actions (defined in
<os.h>
) are:
DYN_ALLOC
DYN_FREE
DYN_CONCAT
DYN_DECONCAT
DYN_DDALLOC
DYN_NOTINUSE
DYN_INQUIRE
Note: The DYN_DDALLOC
action is very specialized.
See IBM documentation for information about the use of DYN_DDALLOC
and
how it differs from DYN_ALLOC
.
The keywords
argument is a pointer to a
character
string containing a list of keywords. The keywords specify
parameters for the request, for instance the name of a data set to be
allocated or the address of a variable in which to store a DDname.
See below for some simple examples of keyword strings.
The libmsgbuf
argument specifies the address of an array of
characters (containing at least 128 bytes) in which any error message
generated by the library is to be stored. If libmsgbuf
is
specified as NULL
, the library writes any error messages to
stderr
, and the texts are not returned to the caller. Note
that in SPE if libmsgbuf
is specified as NULL
, no messages
will be written unless the $WARNING
routine has been replaced,
as described in the
SAS/C Compiler and Library User's Guide, Fourth Edition.
See "DIAGNOSTICS" later in this section for further information on
error handling.
Additional arguments to osdynalloc
may optionally be specified
after the libmsgbuf
argument. These arguments are used to
complete the keywords
string, as shown in the examples below.
Here are a few simple calls to osdynalloc
, to show how
keyword strings are assembled:
rc = osdynalloc(DYN_ALLOC,
"ddn=master,dsn=billing.master.data,disp=shr", NULL);
rc = osdynalloc(DYN_FREE,
"ddn=master,disp=delete,reason=?", NULL, &reason);
reason
.
rc = osdynalloc(DYN_CONCAT,
"ddn=(syslib,syslib1,syslib2),perm", NULL);
rc = osdynalloc(DYN_INQUIRE,
"ddn=master,retdsn=?,retdsorg=?,msgcount=?,errmsgs=?",
libmsgbuf, dsnbuf, &dsorg, &number_msgs, &mvsmsgbuf);
dsnbuf
and dsorg
. If the request fails,
any library message is stored in libmsgbuf
, and the
address of an MVS message buffer is stored in mvsmsgbuf
. Also,
the number of MVS messages is stored in number_msgs
.
keywords
argument to osdynalloc
is just a list
of items separated by commas. Each item is identified by
a keyword, like "ddn"
, "disp"
and
"perm"
in the examples above.
The permitted keywords are determined by the particular action
requested by action
, and are described in tables appearing later
in this description. Each keyword in the string is translated by
osdynalloc
into a single dynamic allocation text unit.
(See Authorized Assembler Language Programs for further
information on text units.) Additional keywords are accepted in
calls to osdynalloc
, regardless of action
, such as
"reason"
and "errmsgs"
in the examples above. These keywords
correspond to fields in the SVC 99 request block, and generally
request special processing options or deal with error-handling.
Syntactically, there are three kinds of keywords
items, as
follows:
"disp=shr"
. These items have the
form "
keyword
=
value
"
.
"ddn=(syslib,syslib2)"
. These
items have the form
"
keyword
=(
value1
,
value2
,...)"
.
If there is only
one value, the parentheses can be left off.
"dummy"
. These items have a keyword, but no
value.
"?"
. This
indicates that the actual keyword value is present in the argument
list as an additional argument. The order of any additional arguments
is the same as the order of the corresponding keywords in the
keywords
string. Note that for multiple value keywords,
each ? corresponds to a single value. That is, you could have a call
like the following:
osdynalloc(DYN_ALLOC, "...volser=(?,?),...", NULL, "VOLUM1", "VOLUM2")
However, you cannot have a call like the following:
osdynalloc(DYN_ALLOC, "...volser=?,...", NULL, "(VOLUM1,VOLUM2)")
The keywords accepted by osdynalloc
are classified into various
sorts based on the type of the associated values:
"member=name"
, that have a value
which is a character string. An argument supplied using the
"?"
convention should have type char *
. With a few exceptions,
string values are automatically translated to upper-case.
"dsn=.project.c"
, that have a
string value that is interpreted as a data set name. If the name
begins with a period, the name is completed by prepending the user's
TSO prefix or (in batch) the userid.
"disp=old"
, that have
a string value which is limited to a prescribed set of values. Except
for this limitation, they are treated as string values. The values
permitted for particular keywords are the values permitted for
the corresponding JCL parameter, unless stated otherwise below.
"blksize=800"
, that have a value
that is a decimal or hexadecimal string. An argument supplied using
the "?"
convention should have type int
.
"retddn=0xf0328"
, that have a
value that is a decimal or hexadecimal address, pointing to an area
where information is to be returned. This must be the address of a
variable of the appropriate type, either int
for numeric
information, or a char
array for string information. In many
cases, the values returned via pointers are encoded. For instance,
a dsorg (data set organization) is returned as an integer with
different bits set depending on the actual file organization.
Information on interpreting these values is given in the IBM book
cited above.
"secmodel="
and "expdt="
). These are discussed
individually in the keyword tables below.
osdynalloc
returns 0
if it was successful. It returns a
negative value if an error was detected by the C library before
the dynamic allocation SVC could be invoked. In this case, a
diagnostic message will have been stored in libmsgbuf
if
this address is not NULL
. If SVC 99 is called and fails,
osdynalloc
returns the value returned in register
15 by SVC 99, as described in Authorized Assembler Language Programs.
Additional information about the error can be obtained by use of
keywords such as "reason"
, "inforeason"
and
"errmsgs"
, as described
in the SVC 99 request block keyword table below.
"path"
keyword is only supported when
OpenEdition MVS is installed.
osdynalloc
is subject to three different sorts of errors.
The first sort is errors detected before calling SVC 99. Examples of
such errors are unrecognized keywords or memory allocation failures.
The SAS/C library generates diagnostics for these failures and either
writes them to stderr
or returns them to the user via the
libmsgbuf
argument. SVC 99 is not issued if one of these errors
occurs.
The second sort is errors detected by SVC 99. Information about these
errors is returned in the osdynalloc
return code, and additional
information can be obtained via keywords like "reason"
.
The library
never diagnoses any of these errors. The "errmsgs"
keyword may
additionally be specified to request that one or more messages about a
failure be returned to the caller. These messages are obtained by a
call to the IBM routine IEFDB476. Note that these messages are
frequently unsuitable for particular applications. (For example, the
message for an out-of-disk-space situation exhorts the user to
"USE THE DELETE COMMAND TO DELETE UNNEEDED DATA SETS
",
even if the
program is not running under TSO.) Also note that the
"issuemsg"
keyword can be used to request that dynamic allocation issue these
messages itself, using either the PUTLINE service or the WTO SVC.
The third sort of error is errors detected by IEFDB476. These errors
are not diagnosed by the library or by MVS, and do not affect the
osdynalloc
return code. The IEFDB476 error codes can be
accessed using the "msgerror"
and "msgreason"
keywords.
osdynalloc
is implemented by the L$UDYNA module, which is
provided in source form. You can modify this module to add or delete
keywords. You might wish to add keywords if functionality is
added to SVC 99 by a new release of MVS. You might wish to delete
keywords if you have a storage-constrained application which does
not need to use some of the more obscure dynamic allocation options
or keywords.
osdynalloc
, regardless of which action is specified.
These keywords are not translated to text units. Rather, they cause
information to be stored in the SVC 99 request block (S99RB) or
request block extension (S99RBX). Most options can be identified by
more than one keyword. This is intended to assist you to easily
locate the keywords you need. Short forms
correspond to the field names defined in
Authorized Assembler Language Programs
, as well as longer names which may be more
understandable or easier to recall.
Note that some options in this table can only be used by authorized programs, as described in the IBM manual.
Table 3.1 SVC 99 Request Block Keywords
Identifier RB Field Value Description Notes ------------------------------------------------------------------ condenq S99CNENQ none Conditionally cnenq ENQ on TIOT ------------------------------------------------------------------ cppl S99ECPPL void * TSO CPPL ecppl address ------------------------------------------------------------------ errmsgs S99EMSGP dyn_msgbuf** Error message (1) errmsg buffer return ermsg address emsgp ------------------------------------------------------------------ errorcode S99ERROR int * Error reason code errorreason return address reasoncode reason error ------------------------------------------------------------------ flags1 S99FLAG1 int First S99RB flag (2) flag1 byte flg1 ------------------------------------------------------------------ flags2 S99FLAG2 int Second S99RB flag (2) flag2 byte flg2 ------------------------------------------------------------------ freereason S99ERCF int * Message free error freeerror code ------------------------------------------------------------------ gdglocate S99GDGNT none Always use the most gdgnt recent GDG catalog informatiom ------------------------------------------------------------------ infoerror S99EERR int * Info retrieval error infoerr code return address eerr ------------------------------------------------------------------ infoinfo S99EINFO int * Info retrieval einfo informational code return address ------------------------------------------------------------------ inforeason S99INFO int * SVC 99 informational infocode reason code return info address ------------------------------------------------------------------ issuemsg S99EIMSG none Send SVC 99 messages sendmsg before returning eimsg ------------------------------------------------------------------ jobsysout S99JBSYS none Treat SYSOUT as jbsys normal job output ------------------------------------------------------------------ key S99EKEY int Storage key for SVC ekey 99 messages emkey ------------------------------------------------------------------ mount S99MOUNT none Allow mounting of volumes ------------------------------------------------------------------ msgbelow S99LSTO none Allocate SVC 99 lsto messages below the 16 meg line ------------------------------------------------------------------ msgcount S99ENMSG int * Number of SVC 99 nmsgs messages return enmsg address nmsg ------------------------------------------------------------------ msgerror none int * Message processing error code (returned in register 15 by IEFDB476) ------------------------------------------------------------------ msgflags S99EOPTS int S99RBX option (2) msgopts bits eopt ------------------------------------------------------------------ msgreason S99ERCO int * Message processing erco reason code address ------------------------------------------------------------------ msgseverity S99EMGSV int Minimum severity (3) msglevel of SVC 99 messages emsgsv msgsv emgsv ------------------------------------------------------------------ mustconvert S99ONCNV none Use an existing oncnv allocation only if it is convertible ------------------------------------------------------------------ noconvert S99NOCNV none Do not convert nocnv an existing allocation ------------------------------------------------------------------ noenq S99TIONQ none Do not ENQ on tionq SYSZTIOT ------------------------------------------------------------------ nomigrate S99NOMIG none Do not recall nomig migrated data sets ------------------------------------------------------------------ nomount S99NOMNT none Do not mount nomnt volumes or consider offline devices ------------------------------------------------------------------ nomsg S99MSGL0 none SVC 99 should no msgl0 issue any messages ------------------------------------------------------------------ noreserve S99NORES none Do not reserve nores datasets ------------------------------------------------------------------ sets offline S99OFFLN none Consider offline offln devices ------------------------------------------------------------------ putlinerc S99EWRC int * PUTLINE/WTO return wtorc code return address wtprc ewrc ------------------------------------------------------------------ smsreason S99ERSN int * SMS reason code ersn return address ------------------------------------------------------------------ subpool S99ESUBP int Subpool number for esubp SVC 99 message emsub subp ------------------------------------------------------------------ unitdevtype S99UDEVT none Interpret unit name udevt as a DEVTYPE value ------------------------------------------------------------------ waitdsn S99WTDSN none Wait for datasets wtdsn ------------------------------------------------------------------ waitunit S99WTUNT none Wait for units wtunit wtunt ------------------------------------------------------------------ waitvol S99WTVOL none Wait for volumes wtvol ------------------------------------------------------------------ wtp S99EWTP none Send messages wto with WTP ewtp ------------------------------------------------------------------
osdynalloc
calls IEFDB476 to turn theS99EMSGP value into an
array of message buffers, a pointer to which is returned to the user
in the variable specified by the keyword. Each element of the array
is of type dyn_msgbuf
. (This type is defined in <os.h>
.)
The buffer should be released by a call to free
after the
messages have been processed.
If an error occurs when the library attempts to convert S99EMSGP
to a message buffer array, (char *) -1
is stored in the return
area. The return value from osdynalloc
is not affected.
(2) Use of these keywords is not recommended because they store an
entire byte of flags. Use of the keywordsfor individual flags
will result in more easily understandable programs. If you use
one of these keywords, any flag bits turned on by previous keywords
in the string will be lost. For instance, if you code the
keywordsnomount,flag1=0x40
, the nomount bit will not be set.
(3) Valid values for this keyword are 0
for all messages,
4
for warning and error messages, and 8
for only error messages.
Tables 3.2 through 3.8 show, for each dynamic allocation action, the
supported keywords and their characteristics. For each keyword,
the table shows the JCL equivalent (if any), the corresponding SVC 99
text unit key (which can be used to locate additional information
about the keyword in Authorized Assembler Language Programs),
the expected C type and format of the keyword value (if any), and
a brief description. For keywords whose values are restricted to
a specific size, char[n]
is shown as the type, where
n
is the array size needed to hold the largest permitted
value. This includes space for a terminating null so that,
for instance, DDnames are shown as char[9]
, even though
the DDname itself is limited to eight characters. For values
shown as pointers to arrays, the array passed must be of exactly
the size shown.
Most options can be identified by more than one keyword. This is intended to assist you in easily locating the keywords you need. Short forms are provided which correspond to the dynamic allocation key names, as well as longer names which may be more understandable or easier to recall.
The Format column of the table may contain one or more of the following values:
"disp="
) or
a string of single-letter flags (for example, "recfm="
).
The permitted
values are described in the IBM documentation, MVS/ESA JCL Reference.
Table 3.2 Dynamic Allocation Keywords
Identifier JCL Equiv SVC 99 Key Value Format Description Notes ---------------------------------------------------------------------------------- accode ACCODE= DALACODE char[9] ANSI tape acode accessibility ---------------------------------------------------------------------------------- code avgrec AVGREC= DALAVGR char * Res Word Average record avgr size multiplier ---------------------------------------------------------------------------------- blocklen SPACE=(len,..) DALBLKLN int Average block blklen length for space blkln allocation ---------------------------------------------------------------------------------- blocksize DCB=BLKSIZE= DALBLKSZ int Maximum block blksiz size blksiz blksz dcbblksize dcbblksz ---------------------------------------------------------------------------------- bufalign DCB=BFALN= DALBFALN char * Res Word Buffer alignment bufaln bfaln dcbbfaln ---------------------------------------------------------------------------------- bufin DCB=BUFIN= DALBUFIN int Number of initial dcbbufin TCAM input ---------------------------------------------------------------------------------- buffers bufmax DCB=BUFMAX= DALBUFMX int Maximum number bufmx of TCAM buffer dcbbufmax dcbbufmx ---------------------------------------------------------------------------------- bufno DCB=BUFNO= DALBUFN int Number of buffers dcbbuf allocate ---------------------------------------------------------------------------------- bufoff DCB=BUFOFF= DALBUFOF int ANSI tape buffer (1) bufof prefix offset dcbbufoff dcbbufof ---------------------------------------------------------------------------------- bufout DCB=BUFOUT= DALBUFOU int Number of initial bufou TCAM output dcbbufout buffers dcbbufou ---------------------------------------------------------------------------------- bufsize DCB=BUFSIZE= DALBUFSZ int TCAM buffer size bufsiz bufsz dcbbufsize dcbbufsz ---------------------------------------------------------------------------------- buftech DCB=BTEKF DALBFTEK char * Res Word Buffering buftek technique bftek dcbbftek ---------------------------------------------------------------------------------- burst BURST= DALBURST char * Res Word 3800 printer burst specification ---------------------------------------------------------------------------------- cdisp DISP=(s,n,cd) DALCDISP char * Res Word Conditional (ABEND) ---------------------------------------------------------------------------------- disposition chars CHARS= DALCHARS char[5] 3800 printer character arrangement table ---------------------------------------------------------------------------------- cntl CNTL= DALCNTL char[27] Reference a CNTL JCL statement ---------------------------------------------------------------------------------- convertible none DALCNVRT none Make this convert allocation cnvrt convertible ---------------------------------------------------------------------------------- copies COPIES= DALCOPYS int Number of copys SYSOUT copies copy ---------------------------------------------------------------------------------- copyg COPIES=(,(g,.)) DALCOPY int Multiple 3800 printer ---------------------------------------------------------------------------------- copy groups cpri DCB=CPRI= DALCPRI char * Res Word TCAM relative dcbcpri transmission priority ---------------------------------------------------------------------------------- cyl SPACE=(CYL,...) DALCYL none Allocate space in cylinersd ---------------------------------------------------------------------------------- dataclass DATACLAS= DALDACL char[9] SMS data class dataclas dacl ---------------------------------------------------------------------------------- dcbddname DCB=* DALDCBD char[9] Copy DCB dcbddn information dcbdd from DD ---------------------------------------------------------------------------------- statement dcbdsname DCB=ds DALDCBDS char[47] Dsname Copy DCB dcbdsn information dcbds from dataset ---------------------------------------------------------------------------------- ddname none DALDDNAM char[9] DDname to ddnam allocate ddn ---------------------------------------------------------------------------------- defer UNIT=(,,DEFER) DALDEFE none Defer unitdefer mounting until open ---------------------------------------------------------------------------------- den DCB=DEN= DALDEN char * Res Word Tape density dcbden ---------------------------------------------------------------------------------- dest DEST= DALSUSER char[9] SYSOUT destnode destination node node suser ---------------------------------------------------------------------------------- destuser DEST=(n,user) DALUSRID char[9] SYSOUT userid destination usrid userid user ---------------------------------------------------------------------------------- diagnstrace DCB=DIAGNS=TRACE DALDIAG none Enable diagnose diagnostic diagns trace diagn dcbdiagns dcbdiagn ---------------------------------------------------------------------------------- dir SPACE=(u,(p,s,d)) DALDIR int Number of directory blocks ---------------------------------------------------------------------------------- disp DISP= DALSTATS char * Res Word Dataset status allocation stats status (NEW,OLD,etc.) ---------------------------------------------------------------------------------- dsname DSN= DALDSNAM char[47] Dsname Name of dsnam dataset to dsn allocate ---------------------------------------------------------------------------------- dsntype DSNTYPE= DALDSNT char * Res Word Special data dsnt set type ---------------------------------------------------------------------------------- dsorg DCB=DSORG= DALDSORG char * Res Word Dataset dcbdsorg organization ---------------------------------------------------------------------------------- dummy DUMMY DALDUMMY none Allocate dummy dataset ---------------------------------------------------------------------------------- erropt DCB=EROPT=OPT= DALEROPT char * Res Word Error handling eropt option dcberroptpt dcberopt ---------------------------------------------------------------------------------- expiration LABEL=EXPDT= DALEXPDT char * Expiration date (2) expires DALEXPDL labelexpdt expdt expdl ---------------------------------------------------------------------------------- fcb FCB= DALFCBIM char[5] Printer FCB fcbim image name ---------------------------------------------------------------------------------- fcbalign FCB= DALFCBAV char * Res Word Request FCB fcbverify (,ALIGN/VERIF) alignment or fcbav verification ---------------------------------------------------------------------------------- flashcount FLASH=(o,count) DALFCNT int Number of fcnt SYSOUT copies to be flashed ---------------------------------------------------------------------------------- flashforms FLASH= DALFFORM char[5] Forms overlay flashform name flash fform ---------------------------------------------------------------------------------- freeclose FREE=CLOSE DALCLOSE none Free file close when closed ---------------------------------------------------------------------------------- func DCB=FUNC= DALFUNC char * Res Word Card reader/punch dcbfunc function ---------------------------------------------------------------------------------- gncp DCB=GNCP= DALGNCP int Number of dcbgncp channel programs for GAM ---------------------------------------------------------------------------------- hold HOLD=YES DALSHOLD none Hold SYSOUT shold for later processing ---------------------------------------------------------------------------------- interchange none DALINCHG int Specify inchg volume interchang media type ---------------------------------------------------------------------------------- interval DCB=INTVL= DALINTV int TCAM invitation intvl interval ---------------------------------------------------------------------------------- ipltxtid DCB=IPLTXID= DALIPLT char[9] 3705 IPL ipltxid text id ipltx dcbipltxtid dcbipltxid dcbipltx ---------------------------------------------------------------------------------- keylen DCB=KEYLEN= DALKYLEN int Key length keyln kylen dcbkeyen dcbkeyln dcbkylen ---------------------------------------------------------------------------------- keyoff KEYOFF= DALKEYO int VSAM key keyo offset ---------------------------------------------------------------------------------- labelinout LABEL=(,,IN/OUT) DALINOUT char * Res Word Input-only labelin or output labelout -only inout ---------------------------------------------------------------------------------- labelpassword LABEL=(,,pw) DALPASPR char * Res Word Password labelp protection labelpswd specification paspr ---------------------------------------------------------------------------------- labelseq LABEL=seq DALDSSEQ int File sequence fileseq number fileno dsseq ---------------------------------------------------------------------------------- labeltype LABEL=(,lt) DALLABEL char * Res Word Type of label tape label ---------------------------------------------------------------------------------- like LIKE= DALLIKE char[47] Dsname Name of a model dataset (SMS) ---------------------------------------------------------------------------------- limct DCB=LIMCT= DALLIMCT int BDAM search dcblimct search limit ---------------------------------------------------------------------------------- lreclk DCB=LRECL=lrK DALLRCK none ANSI tape lreck LRECL is dcblreclk expressed in K dcblreck ---------------------------------------------------------------------------------- lrecl DCB=LRECL= DALLRECL int Logical record (3) dcblrecl record length ---------------------------------------------------------------------------------- member DSN=ds(mem) DALMEMBR char[9] PDS member name membr ---------------------------------------------------------------------------------- mgmtclass MGMTCLAS= DALMGCL char[9] SMS management mgmtclas class mgcl ---------------------------------------------------------------------------------- mode DCB=MODE= DALMODE char * Res Word Card reader dcbmode /punch mode ---------------------------------------------------------------------------------- modify MODIFY= DALMMOD char[4] 3800 printer mmod copy modification module ---------------------------------------------------------------------------------- modifytrc MODIFY=(,trc) DALMTRC int 3800 printer mtrc table reference character ---------------------------------------------------------------------------------- ncp DCB=NCP= DALNCP int Number of dcbncp channel programs ---------------------------------------------------------------------------------- ndisp DISP=(s,n) DALNDISP char * Res Word Normal disposition ---------------------------------------------------------------------------------- optcd DCB=OPTCD= DALOPTCD char * Res Word Optional dcboptcd access method service codes ---------------------------------------------------------------------------------- outlim OUTLIM= DALOUTLM int Output limit outlm for SYSOUT file ---------------------------------------------------------------------------------- output OUTPUT= DALOUTPT char[27] Name of outpt OUTPUT statement ---------------------------------------------------------------------------------- paralell UNIT=(,P) DALPARAL none Mount volumes unitp in parallel paral ---------------------------------------------------------------------------------- password none DALPASSW char[9] Dataset passw password ---------------------------------------------------------------------------------- path PATH= DALPATH char[256] HFS pathname (4) ---------------------------------------------------------------------------------- pathcdisp PATHDISP=(n,c) DALPCDS char * Res Word Conditional pcdisp (ABEND) pcds dispoition cnds for HFS file ---------------------------------------------------------------------------------- pathmode PATHMODE= DALPMDE char * Multiple Res HFS file pmode Word permissions pmde ---------------------------------------------------------------------------------- pathndisp PATHDISP= DALPNDS char * Res Word Normal pathdisp disposition pndisp for HFS file pnds ---------------------------------------------------------------------------------- pathopts PATHOPTS= DALPOPT char * Multiple Res HFS file pathopt Word options popts popt ---------------------------------------------------------------------------------- pcir DCB=PCI=(r,s) DALPCIR char * Res Word PCI handling for dcbpcis receiving ---------------------------------------------------------------------------------- pcis DCB=PCI=(r,s) DALPCIS char * Res Word PCI handling dcbpcis for sending ---------------------------------------------------------------------------------- permalloc none DALPERMA none Allocate permanent permanently perma perm ---------------------------------------------------------------------------------- private VOL=(PRIVATE,.) DALPRIVT none Private privt volume required ---------------------------------------------------------------------------------- protect PROTECT=YES DALPROT none Protect dataset prot with RACF ---------------------------------------------------------------------------------- prtsp DCB=PRTSP= DALPRTS char * Res Word Printer spacing dcbprtsp ---------------------------------------------------------------------------------- qname QNAME= DALQNAME char[18] TCAM queue name ---------------------------------------------------------------------------------- recfm DCB=RECFM= DALRECFM char * Res Word Record format dcbrecfm ---------------------------------------------------------------------------------- recorg RECORG= DALRECO char * Res Word Organization of reco VSAM file ---------------------------------------------------------------------------------- refdd REFDD= DALREFD char[27] Copy DCB a refd attributes from DDname ---------------------------------------------------------------------------------- reserve1 DCB=RESERVE= DALRSRVF int Number of reserve (r1,r2) bytes to be rsrvf reserved in dcbreserve1 first buffer dcbres dcbrsrvf ---------------------------------------------------------------------------------- reserve2 DCB=RESERVE=(r1,r2) DALRSRVS int Number of rsrvs bytes to be dcbreserve2 reserved in dcbrsrvs later buffers ---------------------------------------------------------------------------------- retddname none DALRTDDN char(*)[9] Return DDname rtddname allocated retddn rtddn ---------------------------------------------------------------------------------- retdsnam return DSN= DALRTDSN char(*)[45] Return dsname rtdsname allocated retdsn rtdsn ---------------------------------------------------------------------------------- retdsorg return DCB=DSORG= DALRTO int * Encoded Return dataset rtdsorg organization retorg rtorg ---------------------------------------------------------------------------------- retention LABEL=RETPD= DALRETPD int Retention on labelretpd period retpd ---------------------------------------------------------------------------------- retvolume Return VOL=SER= DALRTVOL char(*)[7] Return volume retvolser serial retvol rtvolume rtvolser rtvol ---------------------------------------------------------------------------------- secmodel SECMODEL= DALSECM char[47] SMS security (5) secm model dataset ---------------------------------------------------------------------------------- segment SEGMENT= DALSEGM int SYSOUT segment page count ---------------------------------------------------------------------------------- spaceformat SPACE=(,,,form) DALSPFRM char * Res Word Format of spform allocated space spfrm ---------------------------------------------------------------------------------- spacerlse SPACE=(,,RLSE) DALRLSE none Release unused release space rlse ---------------------------------------------------------------------------------- spaceround SPACE=(,,,,ROUND) DALROUND none Round up space round request ---------------------------------------------------------------------------------- space1 SPACE=(u,(s1,s2)) DALPRIM int Primary space space allocation primary prime ---------------------------------------------------------------------------------- space2 SPACE=(u,(s1,s2)) DALSECND int Secondary secondary space allocation extend ---------------------------------------------------------------------------------- spin SPIN= DALSPIN char * Res Word Determine when freed SYSOUT should be printed ---------------------------------------------------------------------------------- stack DCB=STACK= DALSTKKC int Card punch dcbstack stacker ---------------------------------------------------------------------------------- storclass STORCLAS= DALSTCL char[9] SMS storage storclas class stcl ---------------------------------------------------------------------------------- sysout SYSOUT= DALSYSOU char[2] Optional sysou Sysout class ---------------------------------------------------------------------------------- sysoutforms SYSOUT=(c,,f) DALSFMNO char[5] SYSOUT forms sysout number formno sysoutform formno forms form sfmno ---------------------------------------------------------------------------------- sysoutpgmname SYSOUT=(c,p) DALSPGNM char[9] SYSOUT writer sysoutpgmnm program name sysoutpgm sysoutwtr programname pgmname wtrname spgnm ---------------------------------------------------------------------------------- subsys SUBSYS= DALSSNM char[5] Subsystem ssnm name ---------------------------------------------------------------------------------- subsysattr none DALSSAT char * Res Word Subsystem (6) ssattr attributes ssatt ---------------------------------------------------------------------------------- subsysparm SUBSYS=(,parm...) DALSSPM char[68] Multiple Subsystem (4) ssparm parameters ssprm ---------------------------------------------------------------------------------- terminal TERM=T DALTERMS none Allocate TSO termts terminal term ---------------------------------------------------------------------------------- thresh DCB=THRESH= DALTHRSH int TCAM message thrsh queue threshold dcbthresh dcbthrsh ---------------------------------------------------------------------------------- tracks SPACE=(TRK,...) DALTRK none Allocate track space to tracks trk ---------------------------------------------------------------------------------- trtch DCB=TRTCH DALTRTCH char * Res Word Tape recording dcbtrtch technique ---------------------------------------------------------------------------------- ucs UCS= DALUCS char[5] SYSOUT UCS or print train ---------------------------------------------------------------------------------- ucsfold UCS=(,FOLD) DALUFOLD none Fold to upper ufold case fold ---------------------------------------------------------------------------------- ucsverify UCS=(,,VERIFY) DALUVRFY none Request UCS uverif verification verify uvrfy ---------------------------------------------------------------------------------- volcount VOL=(,,,count) DALVLCNT int Maximum number of volumes ---------------------------------------------------------------------------------- volrefdsname VOL=REF= DALVLRDS char[46] Dsname Request same volrefdsn volume as vlrds another dataset ---------------------------------------------------------------------------------- volseq VOL=(,,seq) DALVLSEQ int Sequence number vlseq of first volume to mount ---------------------------------------------------------------------------------- volume VOL=SER= DALVLSER char[7] Multiple Names of volser required volumes vol vlser ----------------------------------------------------------------------------------(1) A value of L may be specified for this option in the keywords string. If the value is specified as an extra argument, it must be numeric. An argument value of 0x80 is interpreted as L.
(2) An expiration date may be specified in one of three formats. In a five-digit expiration date, the first two digits are interpreted as the years since 1900. In a seven-digit expiration date, the first four digits are the entire year. The format "yyyy/ddd", as used with the JCL EXPDT keyword, is also supported.
(3) A value of X may be specified for this option in the keywords string. If the value is specified as an extra argument, it must be numeric. An argument value of 0x8000 is interpreted as X.
(4) This parameter value is not translated to upper case.
(5) This keyword has the same syntax as the JCL SECMODEL keyword. That is, it may be specified either as "dsname" or as "(dsname,GENERIC)". In the latter format, the GENERIC must be present in the keyword value and cannot be specified as an extra argument. With either format, if the "?" notation is used, the extra argument may specify only the data set name. That is, the following calls are correct:
osdynalloc(DYN_ALLOC, "secmodel=?", NULL, "SYS1.PARMLIB"); osdynalloc(DYN_ALLOC, "secmodel=(?,GENERIC)", NULL, "SYS1.PARMLIB");while the following are not supported:
osdynalloc(DYN_ALLOC, "secmodel=?", NULL, "(SYS1.PARMLIB,GENERIC)"); osdynalloc(DYN_ALLOC, "secmodel=(?,?), NULL, "SYS1.PARMLIB", "GENERIC");(6) The only value currently accepted for this keyword is SYSIN (requesting a SYSIN data set).
Table 3.3 Dynamic Free Keywords
Identifier JCL Equiv SVC 99 Key Value Format Description Notes ---------------------------------------------------------------------------------- ddname none DUNDDNAM char[9] DDname to ddnam free ddn ---------------------------------------------------------------------------------- dest DEST= DUNOVSUS char[9] SYSOUT destnode destination node node ovsus ---------------------------------------------------------------------------------- destuser DEST=(n,user) DUNOVUID char[9] SYSOUT userid destination user userid ovuid ---------------------------------------------------------------------------------- disp DISP= DUNOVDSP char * Res Word Disposition ndisp (KEEP,DELETE, etc) ovdsp ---------------------------------------------------------------------------------- dsn DSN= DUNDSNAM char[47] Dsname Name of data dsnam set to free dsname ---------------------------------------------------------------------------------- hold HOLD=YES DUNOVSHQ none Hold freed ovshq SYSOUT ---------------------------------------------------------------------------------- member DSN=ds(mem) DUNMEMB char[9] Member name membr to free ---------------------------------------------------------------------------------- nohold HOLD=NO DUNOVSN none Do not hold ovsnh freed SYSOUT ---------------------------------------------------------------------------------- notinuse none DUNREMOV none Remove in-use remove even if remov permanently allocated ---------------------------------------------------------------------------------- path PATH= DUNPATH char[256] HFS path name (1) to free ---------------------------------------------------------------------------------- pathdisp PATHDISP= DUNOVPDS char * Res Word Disposition pathndisp of HFS file ovpds ---------------------------------------------------------------------------------- spin SPIN= DUNSPIN char * Res Word Print freed SYSOUT immediately ---------------------------------------------------------------------------------- sysoutclass SYSOUT= DUNOVCLS char[2l] Overriding sysout SYSOUT class ovcls ---------------------------------------------------------------------------------- unallocate none DUNUNALC none Free even if unalc permanently allocated(1) The value for this keyword is not translated to upper case.
Table 3.4 Dynamic Concatenation Keywords
Identifier JCL Equiv SVC 99 Key Value Format Description Notes ---------------------------------------------------------------------------------- ddnames none DDCDDNAM char[9] Multiple DDname to ddname concatenate ddnam ddn ---------------------------------------------------------------------------------- permanent none DDCPERMC none Concatenate permc permanently perm
Table 3.5 Dynamic Deconcatenation Keywords
Identifier JCL Equiv SVC 99 Key Value Format Description Notes ---------------------------------------------------------------------------------- ddname none DDCDDNAM char[9] DDname to ddnam deconcatenate ddn
Table 3.6 Dynamic Mark Not-in-use Keywords
Identifier JCL Equiv SVC 99 Key Value Format Description Notes ---------------------------------------------------------------------------------- current none DRICURNT none Remove in-use curnt for all allocations except for the current TCB ---------------------------------------------------------------------------------- tcbaddr none DRITCBAD void * Remove in-use tcbad for allocations tcb of this TCB
Table 3.7 Dynamic DDname Allocation Keywords
Identifier JCL Equiv SVC 99 Key Value Format Description Notes ---------------------------------------------------------------------------------- ddname none DDNDDNAM char[9] DDname to be ddnam allocated ddn ---------------------------------------------------------------------------------- retdummy return DDNRTDUM int * Encoded Return DUMMY rtdummy status retdum rtdum
Table 3.8 Dynamic Allocation Inquiry Keywords
Identifier JCL Equiv SVC 99 Key Value Format Description Notes ---------------------------------------------------------------------------------- ddname none DINDDNAM char[9] DDname for ddnam which ddn information is needed ---------------------------------------------------------------------------------- dsname DSN= DINDSNAM char[47] Dsname Dataset for dsnam which dsn information is needed ---------------------------------------------------------------------------------- path PATH= DINPATH char[256] HFS file (1) name for which information is needed ---------------------------------------------------------------------------------- relno none DINRELNO int Relative allocation number for which information is needed ---------------------------------------------------------------------------------- retattr none DINRTATT int * Encoded Return attributes rattr of the allocation retatt rtatt ratt ---------------------------------------------------------------------------------- retavgrec return AVGREC= DINRAVG int * Encoded Return AVGREC rtavgrec specification ravgrec retavgr rtavgr ravgr ---------------------------------------------------------------------------------- retcdisp return DISP=(,,c) DINRTCDP int * Encoded Return conditional rtcdisp disposition rcdisp retcdp rtcdp rcdp ---------------------------------------------------------------------------------- retcntl return CNTL= DINRCNTL char(*)[27] Return referenced rtcntl CNTL statement rcntl ---------------------------------------------------------------------------------- retdataclass return DATACLAS= DINRDACL char(*)[9] Return SMS data rtdataclass class rdataclass retdataclas rtdataclas rdataclas retdacl rtdacl rdacl ---------------------------------------------------------------------------------- retddname none DINRTDDN char(*)[9] Return DDname rtddname rddname retddn rtddn rddn ---------------------------------------------------------------------------------- retdsname none DINRTDSN char(*)[45] Return dataset name rtdsname rdsname retdsn rtdsn rdsn ---------------------------------------------------------------------------------- retdsntype return DSNTYPE= DINRDSNT int * Encoded Return dataset rtdsntype type information rdsntype retdsnt rtdsnt rdsnt ---------------------------------------------------------------------------------- retdsorg return DCB=DSORG= DINRTORG int * Encoded Return dataset rtdsorg organization rdsorg retorg rtorg rorg ---------------------------------------------------------------------------------- retkeyoff return KEYOFF= DINRKEYO int * Return VSAM key rtkeyoff offset rkeyoff retkeyo rtkeyo rkeyo ---------------------------------------------------------------------------------- retlast none DINRTLST int * Encoded Return last rtlast allocation rlast indication retlst rtlst rlst ---------------------------------------------------------------------------------- retlike return LIKE= DINRLIKE char(*)[45] Return name rtlike of model rlike dataset ---------------------------------------------------------------------------------- retlimit none DINRTLIM int * Return number of rtlimit allocations rlimit over the limit retlim rtlim rlim ---------------------------------------------------------------------------------- retmember return DINRTMEM char(*)[9] Return member name DSN=ds rtmember (mem) rmember retmem rtmem rmem ---------------------------------------------------------------------------------- retmgmtclass return DINRMGCL char(*)[9] Return SMS rtmgmtcl MGMTCLAS= management class mgmtclass rmgmtclass retmgmtclas rtmgmtclas rmgmtclas retmgcl rtmgcl rmgcl ---------------------------------------------------------------------------------- retndisp return DISP=(,n) DINRTNDP int * Encoded Return normal rtndisp disposition rndisp retndp rtndp rndp ---------------------------------------------------------------------------------- retpathcdisp return DINRCNDS int * Encoded Return HFS file rtpathcdisp PATHDISP=(n,c) conditional rpathcdisp disposition retpcdisp rtpcdisp rpcdisp retpcds rtpcds rpcds retcnds rtcnds rcnds ---------------------------------------------------------------------------------- retpathmode return DINRPMDE int * Encoded Return HFS rtpathmode file permissions rpathmode retpmode rtpmode rpmode retpmde rtpmde rpmde ---------------------------------------------------------------------------------- retpathopts return DINRPOPT int * Encoded Return HFS rtpathopts PATHOPTS= file options rpathopts retpathopt rtpathopt rpathopt retpopts rtpopts rpopts retpopt rtpopt rpopt ---------------------------------------------------------------------------------- retrecorg return RECORG= DINRRECO int * Encoded Return VSAM rtrecorg file organization rrecorg retreco rtreco rreco ---------------------------------------------------------------------------------- retrefdd return REFDD= DINRREFD char(*)[27] Return REFDD rtrefdd DDname rrefdd retrefd rtrefd rrefd ---------------------------------------------------------------------------------- retsecmodel return DINRSECM struct * Return SMS (2) rtsecmodel SECMODEL= security model rsecmodel information retsecm rtsecm rsecm ---------------------------------------------------------------------------------- retsegment return DINRSEGM int * Return SYSOUT rtsegment SEGMENT= segment page count rsegment retsegm rtsegm rsegm ---------------------------------------------------------------------------------- retspin return SPIN= DINRSPIN int * Encoded Return allocation rtspin SPIN specification rspin ---------------------------------------------------------------------------------- retstatus return DISP=stat DINRTSTA int * Encoded Return allocation rtstatus status rstatus retsta rtsta rsta ---------------------------------------------------------------------------------- retstorclass return DINRSTCL char(*)[9] Return SMS rtstorclass STORCLAS= storage class rstorclass retstorclas rtstorclas rstorclas retstcl rtstcl rstcl(1) The value for this keyword is not translated to upper case.
(2) The value for the "retsecmodel"
keyword is a pointer to an
object of type struct secmodel
, defined in <os.h>
. This
structure includes a field profile
, in which the model
profile name will be stored, and a field generic
, in
which an encoded indication of whether the profile is generic will
be stored. See the IBM publication, the Authorized Assembler Language Programs for
encoding information.
#include <os.h> #include <stdio.h> #include <stdlib.h> #include <string.h> main() { char dsname[45]; char member[9]; char keywords[100]; char pathname[256]; int reason = 0; int rc; rc = osdynalloc(DYN_INQUIRE, "ddn=sysin,retdsn=?,retmem=?,retpath=?,reason=?", NULL, dsname, member, pathname, &reason); if (rc < 0) abort(); /* if input parm error */ if (rc != 0) { if (reason == 0x0438) /* DDname not found */ printf("SYSIN is not allocated.\n"); else printf("osdynalloc inquiry failed, rc = %d, " "reason = %04x\n", rc, reason); exit(EXIT_FAILURE); } if (dsname[0] != 0) { /* the file is a data set */ int l = strlen(dsname); char *lastdot; if (l > 4 && memcmp(dsname+l-4, ".OBJ", 4) == 0) { printf("SYSIN appears to be a .OBJ dataset.\n"); exit(EXIT_FAILURE); } lastdot = strrchr(dsname, '.'); /* find final qualifier */ if (!lastdot) lastdot = dsname+strlen(dsname); if (lastdot+4 > &dsname[44]) { printf("Object data set name too long.\n"); exit(EXIT_FAILURE); } strcpy(lastdot, ".OBJ"); /* replace with .OBJ */ sprintf(keywords, "ddn=sysin,dsn=%s%s%s,disp=shr,reason=?", dsname, (member[0]? ",member=": ""), member); /* build keywords, with or without a member name */ rc = osdynalloc(DYN_ALLOC, keywords, NULL, &reason); if (rc < 0) abort();if (rc != 0) { printf("osdynalloc dsn allocation failed, rc = %d, " "reason = %04x\n", rc, reason); exit(EXIT_FAILURE); } } else { /* else, an HFS path name */ int l = strlen(pathname); char *lastdot; if (l > 2 && memcmp(pathname+l-2, ".o", 2) == 0) { printf("SYSIN appears to be a .o HFS file.\n"); exit(EXIT_FAILURE); } lastdot = strrchr(pathname, '.'); /* find extension */ if (!lastdot) lastdot = pathname+strlen(pathname); if (lastdot+2 > &pathname[255]) { printf("Object data set name too long.\n"); exit(EXIT_FAILURE); } strcpy(lastdot, ".o"); /* replace with .o */ rc = osdynalloc(DYN_ALLOC, "ddn=syslin,path=?,pathdisp=keep," "pathopts=ordonly,reason=?", NULL, pathname, &reason); if (rc < 0) abort(); if (rc != 0) { printf("osdynalloc path allocation failed, rc = %d, ' "reason = %04x\n", rc, reason); exit(EXIT_FAILURE); } } puts("SYSLIN successfully allocated."); exit(EXIT_SUCCESS); }