Chapter Contents |
Previous |
Next |
Direct BSAM Interface Functions |
Portability | SAS/C extension |
SYNOPSIS | |
DESCRIPTION | |
osbdcb | |
osfind | |
osbldl | |
osbopen, osbopenj | |
osfindc | |
osbclose, ostclose | |
osread, oswrite | |
oscheck | |
osnote, ospoint | |
osstow | |
RETURN VALUE | |
IMPLEMENTATION | |
EXAMPLE |
SYNOPSIS |
#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);
DESCRIPTION |
The
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.
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.
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.
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.
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.
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.
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
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.
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.
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.
RETURN VALUE |
Return values are described in the section above on a function-by-function basis.
IMPLEMENTATION |
With the exception of
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.
EXAMPLE |
#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; }
Chapter Contents |
Previous |
Next |
Top of Page |
Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.