MVS Low-Level I/O Functions


This chapter discusses functions that can be used for low level access to MVS sequential data sets. Three sets of functions are provided, two of which perform low-level I/O, and the third of which performs file allocation. There are two I/O interfaces: a full-function interface to BSAM and an interface similar to QSAM. The QSAM-like interface is record-oriented rather than block-oriented, and so is easier to use in many situations. Both of these interfaces access files by DDname, not by data set name. An additional function, 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:

closes a BSAM DCB, and optionally frees the DCB.
allocates and initializes a BSAM DCB.
returns location information for PDS members.
opens a BSAM DCB.
opens a BSAM DCB using a TYPE=J OPEN macro.
checks a read or write for errors.
finds a PDS member.
positions to a PDS member using BLDL data.
returns the current file position.
repositions a file.
reads a block from a file.
temporarily closes a BSAM DCB using a TYPE=T CLOSE macro.
updates a PDS directory.
writes a block to a file.

The record-oriented interface functions are as follows:

closes and frees a DCB opened by osopen.
allocates and initializes a DCB for record access.
flushes pending I/O so the file can be repositioned.
reads a record from a file.
opens a DCB for record access.
opens a DCB for record access using a TYPE=J OPEN macro.
repositions a file.
writes a record to a file.
returns the current file position.

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);



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:

          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.

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.


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 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.


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 values are described in the section above on a function-by-function basis.


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.


This example copies the DDname INPUT to the DDname OUTPUT a block at a time. Only record formats F, V, and VB are handled to avoid code to determine block length. A DCB ABEND exit is provided to intercept B37 and similar ABENDs and terminate execution cleanly in this example.

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;
       char action;
    DCB_t *dcbp;
    void *O_C_EOV_workarea;
    void *recovery_work_area;

 int full;     /* Set to 1 if "file full" ABEND occurs. */

    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.");
    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);
    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.");
       oswrite(output_DECB, output, buf, 0);
       if (oscheck(output_DECB) != 0) {
          if (full) puts("Output file full.");
          else puts("Output error.");

    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.   */
       info->action = 0;      /* Let any other ABEND proceed. */
    return 0;


The Record-Oriented BSAM Interface

The record-oriented BSAM interface is similar to QSAM in many ways, but the use of BSAM permits some useful non-QSAM functionality.

QSAM features supported by the BSAM record interface include the following:

Differences between QSAM and the BSAM record interface include the following:

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. BUFNO=1 and NCP=1
    In this mode, no overlapping of I/O occurs. This mode is most useful for applications that use osseek heavily.
  2. BUFNO=2 and NCP=1
    In this mode, only one I/O operation is active, but a new operation usually starts immediately on completion of the previous request. This enables I/O and program processing to overlap and supports modest use of osseek and ostell.

  3. BUFNO=n and NCP=n-1
    This mode provides for the maximum overlapping of I/O operations and is recommended for maximum efficiency. However, osseek and ostell are difficult or impossible to use.
  4. BUFNO=n and NCP=n
    This mode is used with open mode "updat". osseek and ostell can be used only if n is 1.

Using osseek and ostell

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);



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, 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 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.


See the function descriptions here for return code details.


These functions are implemented by the L$UOSIO module, which issues calls to the direct BSAM interface as necessary to perform I/O.


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();

    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.");
    output = osdcb("output", "recfm=fb,lrecl=80,bufno=10,dsorg=po",
                    out_exlst, 0);
    if (osopen(output, "output", 0)) {
       puts("Output open failed.");

    for (;;) {
       err = osget(input, &rec, &length);
       if (err != 0) {
          if (err != -1) puts("Input error.");
       err = osput(output, rec, length);
       if (err != 0) {
          puts("Output error.");

    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);
       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;

The osdynalloc Function

The following is a description of the osdynalloc function.


 #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:

allocate a data set
free a data set or DDname
concatenate several DDnames
deconcatenate a concatenated DDname
allocate a data set by DDname
mark allocations not in use
obtain information about current allocations

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,,disp=shr", NULL);
allocates the data set BILLING.MASTER.DATA with disposition SHR to the DDname MASTER.
rc = osdynalloc(DYN_FREE,
"ddn=master,disp=delete,reason=?", NULL, &reason);
frees the DDname MASTER with disposition DELETE, and stores the error reason code in the integer reason.
rc = osdynalloc(DYN_CONCAT,
"ddn=(syslib,syslib1,syslib2),perm", NULL);
concatenates the DDnames SYSLIB, SYSLIB1 and SYSLIB2, and marks the concatenation as permanent.
rc = osdynalloc(DYN_INQUIRE,
libmsgbuf, dsnbuf, &dsorg, &number_msgs, &mvsmsgbuf);
finds the name of the data set allocated to the DDname MASTER and its organization, and stores the results in the variables 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.
The 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:

Any keyword value may be specified as the single character "?". 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:
String values
are associated with keywords, such as "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.
Dsname values
are associated with keywords, such as "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.
Reserved-word values
are associated with keywords, such as "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.
Integer values
are associated with keywords, such as "blksize=800", that have a value that is a decimal or hexadecimal string. An argument supplied using the "?" convention should have type int.
Pointer values
are associated with keywords, such as "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.
There are also keywords with specialized value representations (such as "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.


Not all keywords listed below are supported by all versions of MVS. For instance, the "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.


Table 3.1 shows all the keywords that can be used for any call to 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
errorcode    S99ERROR   int *           Error reason code
errorreason                             return address
flags1       S99FLAG1   int             First S99RB flag    (2)
flag1                                   byte
flags2       S99FLAG2   int             Second S99RB flag   (2)
flag2                                   byte
freereason   S99ERCF    int *           Message free error
freeerror                               code
gdglocate    S99GDGNT   none            Always use the most
gdgnt                                   recent GDG catalog
infoerror    S99EERR    int *           Info retrieval error
infoerr                                 code return address
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
jobsysout    S99JBSYS   none            Treat SYSOUT as
jbsys                                   normal job output
key          S99EKEY    int             Storage key for SVC
ekey                                    99 messages
mount        S99MOUNT   none            Allow mounting of
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
msgerror    none       int *            Message processing
                                        error code (returned
                                        in register 15 by
msgflags    S99EOPTS   int              S99RBX option       (2)
msgopts                                 bits
msgreason   S99ERCO    int *            Message processing
erco                                    reason code address
msgseverity S99EMGSV   int              Minimum severity    (3)
msglevel                                of SVC 99 messages
mustconvert S99ONCNV   none             Use an existing
oncnv                                   allocation only
                                        if it is
noconvert   S99NOCNV   none             Do not convert
nocnv                                   an existing
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
smsreason   S99ERSN    int *            SMS reason code
ersn                                    return address
subpool     S99ESUBP   int              Subpool number for
esubp                                   SVC 99 message
unitdevtype S99UDEVT   none             Interpret unit name
udevt                                   as a DEVTYPE value
waitdsn     S99WTDSN   none             Wait for datasets
waitunit    S99WTUNT   none             Wait for units
waitvol     S99WTVOL   none             Wait for volumes
wtp         S99EWTP    none             Send messages
wto                                     with WTP

(1) The value returned is not the value stored in S99EMSGP. 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:

The keyword value is a data set name, and may be specified with an initial period to request that the TSO prefix or userid be prepended.
The stored value is encoded as an integer. See the IBM documentation, the Authorized Assembler Language Programs, book for a description of the encoding for a particular keyword.
The keyword allows more than one value to be specified.
The keyword permits a value to be specified, but one is not required.
Res Word
The keyword value is a reserved word (for example, "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
bufalign    DCB=BFALN=     DALBFALN    char *   Res Word   Buffer alignment
bufin       DCB=BUFIN=    DALBUFIN    int                  Number of initial
dcbbufin                                                    TCAM input
----------------------------------------------------------------------------------                                                            buffers
bufmax      DCB=BUFMAX=    DALBUFMX    int                  Maximum number
bufmx                                                       of TCAM buffer
bufno       DCB=BUFNO=     DALBUFN     int                  Number of buffers
dcbbuf                                                      allocate
bufoff      DCB=BUFOFF=    DALBUFOF     int                 ANSI tape buffer  (1)
bufof                                                       prefix offset
bufout      DCB=BUFOUT=    DALBUFOU     int                 Number of initial
bufou                                                       TCAM output
dcbbufout                                                   buffers
bufsize     DCB=BUFSIZE=   DALBUFSZ     int                 TCAM buffer size
buftech     DCB=BTEKF      DALBFTEK     char *  Res Word    Buffering
buftek                                                      technique
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
                                                             arrangement table
cntl        CNTL=          DALCNTL      char[27]             Reference a
                                                             CNTL JCL
convertible none           DALCNVRT     none                 Make this
convert                                                      allocation
cnvrt                                                        convertible
copies      COPIES=        DALCOPYS     int                  Number of
copys                                                        SYSOUT copies
copyg      COPIES=(,(g,.)) DALCOPY      int      Multiple    3800 printer
----------------------------------------------------------------------------------                                                             copy groups
cpri       DCB=CPRI=       DALCPRI      char *   Res Word     TCAM relative
dcbcpri                                                       transmission
cyl        SPACE=(CYL,...) DALCYL       none                  Allocate space
                                                             in cylinersd
dataclass  DATACLAS=       DALDACL      char[9]              SMS data class
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
defer      UNIT=(,,DEFER)  DALDEFE      none                 Defer
unitdefer                                                    mounting
                                                             until open
den        DCB=DEN=        DALDEN       char *   Res Word    Tape density
dest       DEST=           DALSUSER     char[9]              SYSOUT
destnode                                                     destination
node                                                         node
destuser   DEST=(n,user)   DALUSRID     char[9]              SYSOUT
userid                                                       destination
usrid                                                        userid
diagnstrace DCB=DIAGNS=TRACE DALDIAG    none                 Enable
diagnose                                                     diagnostic
diagns                                                       trace
dir        SPACE=(u,(p,s,d)) DALDIR     int                  Number of
disp       DISP=           DALSTATS   char *   Res Word      Dataset
status                                                       allocation
stats                                                        status
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
expiration LABEL=EXPDT=    DALEXPDT   char *                 Expiration date  (2)
expires                    DALEXPDL
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
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
hold      HOLD=YES         DALSHOLD   none                   Hold SYSOUT
shold                                                        for later
interchange none           DALINCHG   int                    Specify
inchg                                                        volume
                                                             interchang media
interval  DCB=INTVL=       DALINTV   int                     TCAM invitation
intvl                                                        interval
ipltxtid  DCB=IPLTXID=     DALIPLT   char[9]                 3705 IPL
ipltxid                                                      text id
keylen    DCB=KEYLEN=      DALKYLEN  int                     Key length
keyoff    KEYOFF=          DALKEYO   int                     VSAM key
keyo                                                         offset
labelinout LABEL=(,,IN/OUT) DALINOUT char *    Res Word      Input-only
labelin                                                      or output
labelout                                                     -only
labelpassword LABEL=(,,pw) DALPASPR   char *   Res Word      Password
labelp                                                       protection
labelpswd                                                    specification
labelseq  LABEL=seq        DALDSSEQ    int                    File sequence
fileseq                                                       number
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
lrecl    DCB=LRECL=        DALLRECL  int                      Logical record  (3)
dcblrecl                                                      record length
member   DSN=ds(mem)       DALMEMBR  char[9]                 PDS member name
mgmtclass MGMTCLAS=        DALMGCL   char[9]                 SMS  management
mgmtclas                                                     class
mode      DCB=MODE=        DALMODE   char *    Res Word      Card reader
dcbmode                                                      /punch mode
modify    MODIFY=          DALMMOD   char[4]                 3800 printer
mmod                                                         copy modification
modifytrc MODIFY=(,trc)    DALMTRC   int                      3800 printer
mtrc                                                          table reference
ncp       DCB=NCP=         DALNCP    int                      Number of
dcbncp                                                        channel
ndisp    DISP=(s,n)        DALNDISP  char *   Res Word        Normal
optcd    DCB=OPTCD=        DALOPTCD  char *   Res Word        Optional
dcboptcd                                                      access method
                                                              service codes
outlim   OUTLIM=           DALOUTLM  int                      Output limit
outlm                                                         for SYSOUT
output   OUTPUT=           DALOUTPT  char[27]                 Name of
outpt                                                         OUTPUT statement
paralell UNIT=(,P)         DALPARAL  none                     Mount volumes
unitp                                                         in parallel
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
pathndisp PATHDISP=       DALPNDS    char *   Res Word        Normal
pathdisp                                                      disposition
pndisp                                                        for HFS file
pathopts PATHOPTS=        DALPOPT    char *   Multiple Res    HFS file
pathopt                                       Word            options
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
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
qname    QNAME=          DALQNAME  char[18]                  TCAM queue name
recfm    DCB=RECFM=      DALRECFM  char *     Res Word       Record format
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
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
retdsnam return DSN=     DALRTDSN   char(*)[45]              Return dsname
rtdsname                                                     allocated
retdsorg return DCB=DSORG= DALRTO   int *     Encoded       Return dataset
rtdsorg                                                     organization
retention LABEL=RETPD=   DALRETPD   int                     Retention on
labelretpd                                                  period
retvolume Return VOL=SER= DALRTVOL  char(*)[7]             Return volume
retvolser                                                   serial
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
spacerlse SPACE=(,,RLSE) DALRLSE    none                    Release unused
release                                                     space
spaceround SPACE=(,,,,ROUND) DALROUND none                  Round up space
round                                                       request
space1   SPACE=(u,(s1,s2)) DALPRIM  int                     Primary space
space                                                       allocation
space2   SPACE=(u,(s1,s2)) DALSECND int                     Secondary
secondary                                                   space allocation
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
sysout   SYSOUT=         DALSYSOU   char[2]                 Optional
sysou                                                       Sysout class
sysoutforms SYSOUT=(c,,f) DALSFMNO  char[5]                 SYSOUT forms
sysout                                                      number
sysoutpgmname SYSOUT=(c,p) DALSPGNM char[9]                 SYSOUT writer
sysoutpgmnm                                                 program name
subsys   SUBSYS=         DALSSNM    char[5]                 Subsystem
ssnm                                                        name
subsysattr none          DALSSAT    char *    Res Word      Subsystem         (6)
ssattr                                                      attributes
subsysparm SUBSYS=(,parm...) DALSSPM char[68] Multiple     Subsystem         (4)
ssparm                                                      parameters
terminal TERM=T          DALTERMS   none                    Allocate TSO
termts                                                      terminal
thresh   DCB=THRESH=     DALTHRSH   int                     TCAM message
thrsh                                                       queue threshold
tracks   SPACE=(TRK,...) DALTRK     none                     Allocate
track                                                        space to tracks
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
ucsverify UCS=(,,VERIFY) DALUVRFY  none                      Request UCS
uverif                                                       verification
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
(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
dest        DEST=          DUNOVSUS    char[9]             SYSOUT
destnode                                                   destination node
destuser    DEST=(n,user)  DUNOVUID    char[9]             SYSOUT
userid                                                     destination
user                                                       userid
disp        DISP=          DUNOVDSP    char *   Res Word   Disposition
ndisp                                                      (KEEP,DELETE, etc)
dsn         DSN=           DUNDSNAM    char[47] Dsname     Name of data
dsnam                                                      set to free
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
path        PATH=          DUNPATH     char[256]           HFS path name     (1)
                                                           to free

pathdisp    PATHDISP=      DUNOVPDS    char *   Res Word   Disposition
pathndisp                                                  of HFS file
spin        SPIN=          DUNSPIN     char *   Res Word   Print freed
                                                           SYSOUT immediately
sysoutclass SYSOUT=        DUNOVCLS    char[2l]            Overriding
sysout                                                     SYSOUT class
unallocate  none           DUNUNALC    none                Free even if
unalc                                                      permanently
(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
permanent   none           DDCPERMC    none                Concatenate
permc                                                      permanently

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

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
                                                           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
retdummy    return         DDNRTDUM    int *    Encoded    Return DUMMY
rtdummy                                                    status

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
                                                           is needed
relno       none          DINRELNO     int                 Relative
                                                           number for
                                                           which information
                                                           is needed
retattr     none          DINRTATT     int *    Encoded    Return attributes
rattr                                                      of the allocation
retavgrec   return AVGREC= DINRAVG     int *     Encoded   Return AVGREC
rtavgrec                                                   specification
retcdisp    return DISP=(,,c) DINRTCDP int *     Encoded    Return conditional
rtcdisp                                                     disposition
retcntl     return CNTL=      DINRCNTL   char(*)[27]        Return referenced
rtcntl                                                      CNTL statement
retdataclass return DATACLAS= DINRDACL   char(*)[9]        Return SMS data
rtdataclass                                                class
retddname   none              DINRTDDN   char(*)[9]        Return DDname
retdsname none            DINRTDSN   char(*)[45]       Return dataset name
retdsntype return DSNTYPE= DINRDSNT  int *   Encoded   Return dataset
rtdsntype                                              type information
retdsorg return DCB=DSORG= DINRTORG  int *   Encoded   Return dataset
rtdsorg                                               organization
retkeyoff return KEYOFF=   DINRKEYO   int *            Return VSAM key
rtkeyoff                                              offset
retlast none               DINRTLST   int *  Encoded   Return last
rtlast                                                 allocation
rlast                                                  indication
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
retmember return           DINRTMEM   char(*)[9]       Return member name
rtmember  (mem)
retmgmtclass return        DINRMGCL   char(*)[9]       Return SMS
rtmgmtcl         MGMTCLAS=                                 management class
retndisp  return DISP=(,n) DINRTNDP   int *  Encoded   Return normal
rtndisp                                                disposition
retpathcdisp return        DINRCNDS   int *  Encoded   Return HFS file
rtpathcdisp  PATHDISP=(n,c)                            conditional
rpathcdisp                                             disposition
retpathmode return         DINRPMDE   int *  Encoded   Return HFS
rtpathmode                                             file permissions
retpathopts return        DINRPOPT   int *  Encoded   Return HFS
rtpathopts   PATHOPTS=                                 file options
retrecorg return RECORG=  DINRRECO   int *   Encoded   Return VSAM
rtrecorg                                               file organization
retrefdd  return REFDD=  DINRREFD   char(*)[27]        Return REFDD
rtrefdd                                                DDname
retsecmodel return       DINRSECM   struct *          Return SMS         (2)
rtsecmodel  SECMODEL=                                 security model
rsecmodel                                             information
retsegment return        DINRSEGM   int *             Return SYSOUT
rtsegment  SEGMENT=                                   segment page count
retspin return SPIN=     DINRSPIN   int *    Encoded  Return allocation
rtspin                                                SPIN specification
retstatus return DISP=stat DINRTSTA  int *    Encoded  Return allocation
rtstatus                                              status
retstorclass return       DINRSTCL  char(*)[9]        Return SMS
rtstorclass    STORCLAS=                               storage class

(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.


This example uses the inquiry function of SVC 99 to determine the name of the file allocated to the DDname SYSIN. It then derives the name of an object data set from the returned name, and allocates that name to the DDname SYSLIN.
 #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,
                    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);

    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");
       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");
       strcpy(lastdot, ".OBJ");          /* replace with .OBJ */
               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);
    } 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");
       lastdot = strrchr(pathname, '.');   /* find extension */
       if (!lastdot) lastdot = pathname+strlen(pathname);
       if (lastdot+2 > &pathname[255]) {
          printf("Object data set name too long.\n");
       strcpy(lastdot, ".o");            /* replace with .o */
       rc = osdynalloc(DYN_ALLOC,
                       "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);

    puts("SYSLIN successfully allocated.");

Copyright (c) 1998 SAS Institute Inc. Cary, NC, USA. All rights reserved.