Chapter Contents |
Previous |
Next |
BSAM Record-Oriented Interface Functions |
Portability | SAS/C extension |
SYNOPSIS | |
DESCRIPTION | |
osdcb | |
osopen, osopenj | |
osclose | |
osget | |
osput | |
osflush | |
ostell | |
osseek | |
RETURN VALUE | |
IMPLEMENTATION | |
EXAMPLE |
SYNOPSIS |
#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);
DESCRIPTION |
The
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
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
.
osopen
and
osopenj
return
0
if successful or nonzero if
unsuccessful.
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.
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.
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
.
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.
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.
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.
RETURN VALUE |
See the function descriptions here for return code details.
IMPLEMENTATION |
EXAMPLE |
This example copies the contents of DDname
INPUT to the DDname OUTPUT, and then uses the
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; }
Chapter Contents |
Previous |
Next |
Top of Page |
Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.