HP OpenVMS Systems

C Programming Language
Content starts here HP C

User's Guide for OpenVMS Systems

Previous Contents Index

Chapter 2
Using OpenVMS Record Management Services

HP C for OpenVMS systems provides a set of run-time library functions and macros to perform I/O. Some of these functions perform in the same manner as I/O functions found on C implementations running on UNIX systems. Other HP C functions take full advantage of the functionality of the OpenVMS file-handling system. You can also access the OpenVMS file-handling system from your HP C program without using the HP C Run-Time Library (RTL) functions. In any case, the system that ultimately accesses files on OpenVMS systems is OpenVMS Record Management Services (RMS).

This chapter introduces you to the following RMS topics:

The file-handling capabilities of HP C fall into two distinct categories:

  • The HP C RTL functions which, with little or no modification, are portable to other C implementations
  • The RMS functions, which are not portable to other C implementations, but do provide more methods of file organization and more record access modes

This chapter briefly reviews the basic concepts and facilities of RMS and shows examples of their application in HP C programming. Because this is an overview, the chapter does not explain all RMS concepts and features. For language-independent information about RMS, see the following manuals in the OpenVMS documentation set:

  • Guide to OpenVMS File Applications
    This guide contains a general description of the record management services of the OpenVMS operating system, and the file creation and run-time options available.
  • OpenVMS Record Management Services Reference Manual
    This manual describes the user interface to RMS. It includes introductory information on RMS programming and detailed definitions of all RMS control block structures and macro instructions.

2.1 RMS File Organization

RMS supports three types of file organization:

  • Sequential
  • Relative
  • Indexed

The following sections describe these types of file organization.

The organization of a file determines how a file is stored on the media and, consequently, the possible operations on records. You specify the file's organization when you create the file; it cannot be changed.

However, you can use the File Definition Language Editor (FDL) and the CONVERT utility to define the characteristics of a new file, and then fill the new file with the contents of the old file of a different format. For more information, see the OpenVMS Utility Routines Manual.

2.1.1 Sequential File Organization

Sequential files have consecutive records. There are no empty records separating records that contain data. This organization allows the following operations on the file:

  • Positioning the file at a particular record, generally by sequentially moving from one record to the next.
    Direct access is also possible, either by key (relative record number) or by the record file address (RFA). However, although allowed for any file organization, access by RFA is limited to files on disk devices, and access by key is limited to disk files that also have fixed-length records. These access modes are unusual because most application programs do not keep track of record positions in sequential files.
  • Reading data from any record.
  • Writing data by adding records at the end of the file.

Sequential organization is the only kind permitted for magnetic tape files and other nondisk devices.

2.1.2 Relative File Organization

Relative files have records that occupy numbered, fixed-length cells. The records themselves need not have the same length. Cells can be empty or can contain records so the following operations are permitted:

  • Positioning the file at a particular record, usually by direct access.
    In direct access, RMS uses the relative record number---the number of a cell---as a key to locate the cell and its record; there is no need to reference other cells. RMS can also access the records sequentially by ignoring empty cells, or RMS can access the file directly with the record file address (RFA). RMS returns the RFA in a parameter block whenever it writes a record, and you can access and use the RFA to locate the appropriate record. You can access any file organization with the RFA.
  • Reading a record from any cell.
  • Deleting a record from any cell.
  • Writing a record into any cell.

Relative file organization is possible only on disk devices.

2.1.3 Indexed File Organization

Indexed files have records that contain, in addition to data and carriage-control information, one or more keys. Keys can be character strings, packed decimal numbers, and 16-bit, 32-bit, or 64-bit signed or unsigned integers. Every record has at least one key, the primary key, whose value in each record cannot be changed. Optionally, each record can have one or more alternate keys, whose key values can be changed.

Unlike relative record numbers used in relative files, key values in indexed files are not necessarily unique. When you create a file, you can specify that a particular key have the same value in different records (these keys are called duplicate keys). Keys are defined for the entire file in terms of their position within a record and their length.

In addition to maintaining its records, RMS builds and maintains indexes for each of the defined keys. As records are written to the file, their key values are inserted in order of ascending value in the appropriate indexes. This organization allows the following operations:

  • Positioning the file at a particular record by direct access.
    In direct access reads, you use either a primary or alternate key, plus a specified key value, to locate the record. In direct access writes (given a record that contains key values in the predefined positions), RMS automatically adds the record to the file and adds the primary and alternate key values to the appropriate indexes. You can also access records sequentially, where the sequence is defined by the index for a specified key. Finally, you can access records directly by RFA; RMS returns the RFA in a parameter block whenever it writes a record, and you can access and use the RFA to locate the appropriate record. You can access any file organization with the RFA.
  • Reading any record, including sequential reads controlled by a key's index.
  • Deleting any record.
  • Updating an alternate key's value, if the key's definition permits its value to change.
  • Writing records selectively, based on the value of a key and, when allowed in the key's definition, based on duplicate values. If duplicate values are permitted, you can write records containing key values that are present in the key's index. If duplicate values are not permitted, such write operations are rejected.

Indexed organization is possible only on disk devices.

2.2 Record Access Modes

The record access modes are sequential, direct by key, and direct by record file address. The direct access modes are possible only with files that reside on disks.

Unlike a file's organization, the record access mode is not a permanent attribute of the file. During the processing of a file, you can switch from one access mode to any other permitted for that file organization. For example, indexed files are often processed by locating a record directly by key, and then using that key's index to sequentially read all the indexed records in ascending order of their key values; this method is sometimes called the indexed-sequential access method (ISAM).

2.3 RMS Record Formats

Records in RMS files can have the following formats:

  • Fixed-length format, where the length of every record is defined at the time of the file's creation. This format is permitted with any file organization.
  • Variable-length format, where the maximum length of every record is defined at the time of the file's creation. This format is permitted with any file organization.
  • Variable-length format with a fixed-length control area (VFC), where every record is prefixed by a fixed-length field. This format is permitted only with sequential and relative files.
  • Stream format, where records are delimited by special characters called terminators. Terminators are part of the record they delimit. The three types of stream formatting are as follows:
    • Stream, where records can be delimited with a form feed, vertical tab, new-line character, or carriage-return/new-line character.
    • Stream_cr, where records are delimited with the carriage-return character.
    • Stream_lf, where records are delimited with the line-feed character. This format variation is the default format when you create files using the Standard I/O functions.

2.4 RMS Functions

RMS provides a number of functions that create and manipulate files. These functions use RMS data structures to define the characteristics of a file and its records. The data structures are used as indirect arguments to the function call.

The RMS data structures are grouped into four main categories, as follows:

  • File Access Block (FAB)---Defines the file's characteristics, such as file organization and record format.
  • Record Access Block (RAB)---Defines the way in which records are processed, such as the record access mode.
  • Extended Attribute Block (XAB)---Various kinds of extended attribute blocks contain additional file characteristics, such as the definition of keys in an indexed file. Extended attribute blocks are optional.
  • Name Block (NAM)---Defines all or part of a file specification to be used when an incomplete file specification is given in an OPEN or CREATE operation. Name blocks are optional.

RMS uses these data structures to perform file and record operations. Table 2-1 lists some of the common functions.

Table 2-1 Common RMS Run-Time Processing Functions
Category Function Description
sys$create Creates and opens a new file of any organization.
  sys$open Opens an existing file and initiates file processing.
  sys$close Terminates file processing and closes the file.
  sys$erase Deletes a file.
sys$connect Associates a file access block with a record access block to establish a record access stream; a call to this function is required before any other record-processing function can be used.
  sys$get Retrieves a record from a file.
  sys$put Writes a new record to a file.
  sys$update Rewrites an existing record to a file.
  sys$delete Deletes a record from a file.
  sys$rewind Positions the record pointer to the first record in the file.
  sys$disconnect Disconnects a record access stream.

All RMS functions are directly accessible from HP C programs. The syntax for any RMS function has the following form:

int sys$name(struct rms_structure *pointer);

In this syntax, name is the name of the RMS function (such as OPEN or CREATE); rms_structure is the name of the structure being used by the function.

The file-processing functions require a pointer to a file access block as an argument; the record-processing functions require a pointer to a record access block as an argument. Since sys$create is a file-processing function, its syntax is as follows:

int sys$create(struct FAB *fab);

These syntax descriptions do not show all the options available when you invoke an RMS function. For a complete description of the RMS calling sequence, see the OpenVMS Record Management Services Reference Manual.

Finally, all the RMS functions return an integer status value. The format of RMS status values follows the standard format described in Chapter 3. Since RMS functions return a 32-bit integer, you do not need to declare the type of an RMS function return before you use it.

2.5 Writing HP C Programs Using RMS

The HP 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 HP 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 HP 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 HP 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 HP 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:


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

Previous Next Contents Index