2.5 Writing DEC C Programs Using RMS

The DEC C Run-Time Library (RTL) supplies a number of header files that describe the RMS data structures and status codes. Table 2-2 describes these header files.

Table 2-2 DEC C RMS Header Files

Header File  Structure Tag(s)  Description 
<fab.h>  FAB  Defines the file access block structure. 
<rab.h>  RAB  Defines the record access block structure. 
<nam.h>  NAM  Defines the name block structure. 
<xab.h>  XAB  Defines all the extended attribute block structures. 
<rmsdef.h>  Defines the completion status codes that RMS returns after every file- or record-processing operation. 
<rms.h>  all tags  Includes all the previous header files. 

Most DEC C programmers include the <rms.h> header file, which includes all the other header files.

These header files define all the data structures as structure tag names. However, they perform no allocation or initialization of the structures; these header files describe only a template for the structures. To use the structures, you must create storage for them and initialize all the structure members as required by RMS. Note that these include files are part of DEC C for OpenVMS systems. RMS is part of the OpenVMS environment and may contain other included header files not described here.

To assist in the initialization process, the DEC C RTL provides initialized RMS data structure variables. You can copy these variables to your uninitialized structure definitions with a structure assignment. You can choose to take the default values for each of the structure members, or you can tailor the contents of the structures to fit your requirements. In either case, you must use the structure types to allocate storage for the structure and to define the members of the structure.

The initialized variables supply the RMS default values for each member in the structure; they specify none of the optional parameters. To determine what default values are supplied by the initialized variables, see the OpenVMS Record Management Services Reference Manual.

Table 2-3 lists the initialized RMS data structure variables and the structures that they initialize.

Table 2-3 RMS Data Structures

Variable  Structure Type  Initialize Structure 
cc$rms_ fab  struct FAB  File access block 
cc$rms_rab  struct RAB  Record access block 
cc$rms_nam  struct NAM  Name block 
cc$rms_xaball  struct XABALL  Allocation extended attribute block 
cc$rms_xabdat  struct XABDAT  Date and time extended attribute block 
cc$rms_xabfhc  struct XABFHC  File header characteristics extended attribute block 
cc$rms_xabkey  struct XABKEY  Indexed file key extended attribute block 
cc$rms_xabpro  struct XABPRO  Protection extended attribute block 
cc$rms_xabrdt  struct XABRDT  Revision date and time extended attribute block 
cc$rms_xabsum  struct XABSUM  Summary extended attribute block 
cc$rms_xabtrm  struct XABTRM  Terminal extended attribute block 

The declarations of these structures are contained in the appropriate header file.

The names of the structure members conform to the following RMS naming convention:

typ$s_fld

The identifier typ is the abbreviation for the structure, the letter s is the size of the member (such as l for longword or b for byte), and the identifier fld is the member name, such as sts for the completion status code. The dollar sign ($) is a character used in OpenVMS system logical names. See the OpenVMS Record Management Services Reference Manual for a description of the members in each structure.

2.5.1 Initializing File Access Blocks

The file access block defines the attributes of the file. To initialize a file access block, assign the values in the initialized data structure cc$rms_fab to the address of the file access block defined in your program. Consider the following example:

/*  This example shows how to initialize a file access block.   */

#include <rms.h>               /*  Declare all RMS data structs */

struct  FAB   fblock;          /*  Define a file access block   */


main()
{
   fblock = cc$rms_fab;        /*  Initialize the structure     */
      .
      .
      .
}

Any of these RMS structures may be dynamically allocated. For example, another way to allocate a file access block is as follows:

/* This program shows how to dynamically allocate RMS structures. */

#include <rms.h>                 /*  Declare all RMS data structs */


main()
{
                                 /*  Allocate dynamic storage     */
   struct  FAB     *fptr = malloc(sizeof (struct FAB));
   *fptr = cc$rms_fab;           /*  Initialize the structure     */
      .
      .
      .
}

To change the default values supplied by a data structure variable, you must reinitialize the members of the structure individually. You initialize a member by giving the offset of the member and assigning a value to it. Consider the following example:

fblock.fab$l_xab = &primary_key;

This statement assigns the address of the extended attribute block named primary_key to the fab$l_xab member of the file access block named fblock.

2.5.2 Initializing Record Access Blocks

The record access block specifies how records are processed. You initialize a record access block the same way you initialize a file access block. For example:

/*  This example shows how to initialize a file access block.  */

#include <rms.h>
struct  FAB  fblock;

struct  RAB  rblock;          /*  Define a record access block */


main()
{
   fblock = cc$rms_fab;       /*  Initialize the structure     */
   rblock = cc$rms_rab;

                              /*  Initialize the FAB member    */
   rblock.rab$l_fab  =  &fblock;
      .
      .
      .
}

2.5.3 Initializing Extended Attribute Blocks

There is only one extended attribute block structure (XAB), but there are seven ways to initialize it. The extended attribute blocks define additional file attributes that are not defined elsewhere. For example, the key extended attribute block is used to define the keys of an indexed file.

All extended attribute blocks are chained off a file access block in the following manner:

  1. In a file access block, you initialize the fab$l_xab field with the address of the first extended attribute block.

  2. You designate the next extended attribute block in the chain in the xab$l_nxt field of any subsequent extended attribute blocks. You chain each subsequent extended attribute block in order by the key of reference (first the primary key, then the first alternate key, then the second alternate key, and so forth).

  3. You initialize the xab$l_nxt member of the last extended attribute block in the chain with the value 0 (the default) to indicate the end of the chain.

You go through the same steps to declare extended attribute blocks as you would to declare the other RMS data structures:

  1. Define the structures by including the appropriate header file.

  2. Assign a specific data structure variable to the structure in your program.

  3. Initialize the members of the structure with the desired values.

The following example declares two extended attribute block structures. They are initialized as key extended attribute blocks with the cc$rms_xabkey data structure variable. The xab$l_nxt member of the primary key is initialized with the address of the alternate_ key extended attribute block.

/*  This example shows how to initialize the extended          *
 *  attribute block.                                           */

#include <rms.h>
struct  XABKEY  primary_key,alternate_key;


main()
{
   primary_key           = cc$rms_xabkey;
   alternate_key         = cc$rms_xabkey;
   primary_key.xab$l_nxt = &alternate_key;
      .
      .
      .
}

2.5.4 Initializing Name Blocks

The name block contains default file name values, such as the directory or device specification, file name, or file type. If you do not specify one of the parts of the file specification when you open the file, RMS uses the values in the name block to complete the file specification and places the complete file specification in an array.

You create and initialize name blocks in the same manner used to initialize the other RMS data structures. Consider the following example:

/*  This example shows how to initialize a name block.         */

#include <rms.h>

struct  NAM  nam;
struct  FAB  fab;


main()
{
   fab = cc$rms_fab;
   nam = cc$rms_nam;


                              /*  Define an array for the      *
                               *   expanded file specification */
   char expanded_name[NAM$C_MAXRSS];

                              /*  Initialize the appropriate   *
                               *   members                     */
   fab.fab$l_nam = &nam;
   nam.nam$l_esa = &expanded_name;
   nam.nam$b_ess =  sizeof  expanded_name;
      .
      .
      .
}


Previous Page | Next Page | Table of Contents | Index