VX/RMS - SYS$ Routines for RMS
Overview
VX/RMS is a call-compatible library that runs OpenVMS RMS applications on Linux and Windows without source code changes. It presents the OpenVMS RMS callable interface: the SYS$ record and file services operating on the familiar FAB, RAB, XAB, and NAM control blocks, so recompiled programs open, read, write, and lock records exactly as they did on VMS.
Underneath, VX/RMS is an emulation layer rather than a re-implementation of VAX or Alpha RMS internals. Sequential and relative files map onto plain host files, indexed files map onto a D-ISAM keyed store, VMS file specifications and logical names are translated automatically, and native host error codes are mapped back to their VMS RMS equivalents. Programs keep their VMS file organizations, access modes, record formats, and locking behaviour on the new platform.
<!-- Webflow embed (min). Source: vx-rms-page-technical/rms-tech-body-embed-dark.html → python3 website/embeds/minify_webflow_embed.py … -->
<div class="s7-tech-embed" data-vxrmsd-body-embed="1" data-technical-mega-embed="1" lang="en"><h2 id="architecture">Architecture and how it maps to the host</h2><p>
VX/RMS is a linked runtime library, not a server or daemon. It is archived into
<code>libvxrt.a</code>, the same runtime archive shared with the other VX/TOOLS routines, and
linked directly into the migrated application. There is no RMS process to administer: every
record operation is serviced in-process by the library, which presents the OpenVMS RMS
callable interface on top of ordinary host files.
</p><p>
Each RMS file organization is mapped onto a concrete host storage mechanism. Record I/O for
sequential and relative files uses plain file reads, writes, and seeks; indexed files are
backed by a D-ISAM keyed store; locking uses host byte-range locks for sequential and relative
files and D-ISAM record locks for indexed files. Filename and version machinery is emulated on
top of the host directory tree.
</p><div class="table-wrapper"><table><thead><tr><th>RMS organization</th><th>Host storage</th><th>Locking</th><th>Notes</th></tr></thead><tbody><tr><td>Sequential</td><td>Plain host file</td><td>Byte-range locks</td><td>Optional 44-byte file-header block records RAT, RFM, and MRS.</td></tr><tr><td>Relative</td><td>Plain host file</td><td>Byte-range locks</td><td>Records carry a 3-byte VMS-shaped header (control byte plus 2-byte length).</td></tr><tr><td>Indexed</td><td>D-ISAM keyed store</td><td>D-ISAM record locks</td><td>Primary and secondary keys build a companion index alongside the data file.</td></tr></tbody></table></div><div class="callout"><strong>No server to administer.</strong> VX/RMS has no daemon and no IPC substrate to
configure. The library reads and writes the host files directly, in the address space of the
migrated program, so deployment is a link step rather than a service install.
</div><h6>Layering</h6><p>The runtime sits between the unchanged application and the host file system:</p><style>.s7-tech-embed .rms-flow {margin: 1.5rem 0;padding: 16px;border: 1px solid var(--s7t-border);border-radius: 10px;background: rgba(255, 255, 255, 0.01);}.s7-tech-embed .rms-flow-node {min-width: 0;padding: 14px 16px;border-radius: 8px;background: var(--s7t-surface);color: var(--s7t-text);}.s7-tech-embed .rms-flow-node strong,.s7-tech-embed .rms-flow-node span {display: block;}.s7-tech-embed .rms-flow-node strong {margin-bottom: 4px;}.s7-tech-embed .rms-flow-node span {color: var(--s7t-muted);font-size: 0.9em;line-height: 1.45;}.s7-tech-embed .rms-flow-label {margin: 8px 0;color: var(--s7t-accent);font-family: var(--s7t-mono);font-size: 0.76em;font-weight: 700;letter-spacing: 0.08em;text-align: center;text-transform: uppercase;}.s7-tech-embed .rms-flow-branches {display: grid;grid-template-columns: repeat(2, minmax(0, 1fr));gap: 10px;}.s7-tech-embed .rms-flow-branch {border-top: 3px solid var(--s7t-accent);background: var(--s7t-surface2);}.s7-tech-embed .rms-flow-output {border: 1px solid var(--s7t-note-bd);background: var(--s7t-note-bg);}@media (max-width: 800px) {.s7-tech-embed .rms-flow-branches {grid-template-columns: 1fr;}}</style><div class="rms-flow" aria-label="VX/RMS application, runtime, storage, and locking layers"><div class="rms-flow-node"><strong>Migrated application</strong><span>Unchanged <code>SYS$</code> and <code>EXE$</code> calls</span></div><div class="rms-flow-label">Calls into</div><div class="rms-flow-node"><strong>VX/RMS</strong><span>In-process runtime in <code>libvxrt.a</code></span></div><div class="rms-flow-label">Selects storage by file organization</div><div class="rms-flow-branches"><div class="rms-flow-node rms-flow-branch"><strong>Plain host files</strong><span>Sequential and relative organizations</span></div><div class="rms-flow-node rms-flow-branch"><strong>D-ISAM keyed store</strong><span>Indexed organization</span></div></div><div class="rms-flow-label">Converges on host storage and locking</div><div class="rms-flow-node rms-flow-output"><strong>Host file system</strong><span>Byte-range locks for plain files and record locks for indexed files</span></div></div><p>
The library also emulates the file-header block that VX/RMS optionally writes at the front of
sequential and relative files. This can be turned off with the <code>IGNORE_FHC</code>,
<code>NOFHC</code>, or <code>EXTUNIX</code> configuration options to produce a plain host file
with no VMS-specific header, which is useful when the data needs to be read by native host
tooling as well.
</p><h2 id="call-model">The SYS$ and EXE$ call model</h2><p>
Every RMS service is exposed as a two-layer pair so existing object references and calling
conventions resolve without change. The outer <code>SYS$</code> entry is the canonical caller
name; the inner <code>EXE$</code> entry does the work and is used internally by the runtime.
</p><div class="table-wrapper"><table><thead><tr><th>Layer</th><th>Role</th><th>Callbacks</th></tr></thead><tbody><tr><td><code>SYS$xxx</code></td><td>Outer user entry. Takes two extra error and success AST callback pointers, then wraps the <code>EXE$xxx</code> call.</td><td>Fires AST callbacks when enabled.</td></tr><tr><td><code>EXE$xxx</code></td><td>Inner entry that performs the operation. Called directly from inside the runtime, for example when <code>EXE$CREATE</code> opens an existing file.</td><td>No AST callbacks.</td></tr></tbody></table></div><p>
Each service is aliased to upper-case, lower-case, and trailing-underscore forms
(<code>sys$xxx_</code>, <code>exe$xxx_</code>), so Fortran callers reach the same body with no
separate thunk. The two-layer wrapper shape is consistent across every routine:
</p>
<pre><span class="kw">extern</span> <span class="str">"C"</span> U32 SYS_D_OPEN( FABDEF *fab,
U32 (*error)(<span class="kw">void</span>),
U32 (*success)(<span class="kw">void</span>) )
{
<span class="cmt">// do the work through the inner entry</span>
U32 rc = EXE_D_OPEN(fab);
<span class="cmt">// AST callbacks fire only when RMSAST=Y (off by default)</span>
<span class="kw">if</span> (vxrt_RMS_Ast_Enable()) {
<span class="kw">if</span> (success && ODD(rc)) (*success)();
<span class="kw">else if</span> (error && !ODD(rc)) (*error)();
}
<span class="kw">return</span> rc;
}
<span class="cmt">// aliased to SYS$OPEN, sys$open, and sys$open_</span></pre>
<h6>AST gating</h6><div class="callout warn"><strong>Callbacks are off by default.</strong> The error and success ASTs fire only when the
<code>RMSAST</code> configuration option is set to <code>Y</code>. With it off, portable callers
may pass null for the two callback pointers safely. With <code>RMSAST=Y</code>, passing null for
a callback that is needed will dereference it, matching the original VMS behaviour.
</div><h6>Status convention</h6><p>
Every routine returns a 32-bit VMS-style condition code by value: the low bit set means success.
Test it with <code>ODD(status)</code>. There are no signal-raising paths: conditions that native
VMS would raise as an exception are returned by value instead (usually <code>RMS$_FAB</code> or
<code>RMS$_RAB</code>). A process-wide <code>RMS_STATUS</code> global is set as a side effect of
almost every routine, which makes RMS calls non-reentrant across threads.
</p><h2 id="control-structures">Control structures: FAB, RAB, XAB, NAM</h2><p>
VX/RMS operates on the same control blocks as native OpenVMS RMS. Application code fills these
structures, passes them by reference, and reads results back from the same fields. The layouts
are byte-compatible with the VMS definitions so recompiled programs bind to them unchanged.
</p><div class="table-wrapper"><table><thead><tr><th>Block</th><th>Purpose</th><th>Key fields and notes</th></tr></thead><tbody><tr><td><code>FAB</code> (File Access Block)</td><td>Describes the file: name, organization, record format, and sharing.</td><td>Organization <code>FAB$B_ORG</code> selects sequential, relative, or indexed. Set up before <code>SYS$OPEN</code> or <code>SYS$CREATE</code>.</td></tr><tr><td><code>RAB</code> (Record Access Block)</td><td>Describes a record stream connected to an open file.</td><td>Access mode <code>RAB$B_RAC</code> selects sequential, keyed, or record-file-address access. A 64-bit variant carries wide buffer and size slots for <code>SYS$GET</code>.</td></tr><tr><td><code>XAB</code> (Extended Attribute Blocks)</td><td>Optional chain of attribute blocks hung off the FAB or RAB.</td><td>Recognised types include allocation, date, file-header, key, protection, and summary blocks, plus a host-specific block reporting the underlying file name and companion index and data files.</td></tr><tr><td><code>NAM</code> (Name Block)</td><td>Holds filename parse state and results.</td><td>Expanded and resultant string areas plus wildcard context. Directory and file identifiers are populated with host inode numbers rather than VMS file identifiers.</td></tr></tbody></table></div><h6>XAB chain</h6><p>
Extended attribute blocks form a singly-linked chain located with a runtime helper. The
file-header attribute block is the 44-byte header VX/RMS writes at the front of relative and
sequential files; one key attribute block describes each key of an indexed file. Journalling and
recovery-unit attribute blocks are recognised so that parsing does not error, but the underlying
features are not implemented (see the compatibility matrix).
</p><h2 id="routines">SYS$ routine reference</h2><p>
VX/RMS exports the OpenVMS RMS callable services. Each service is available under its
<code>SYS$</code> name (the canonical caller entry), an <code>EXE$</code> inner variant, and the
Fortran trailing-underscore aliases. The tables below group the routines by function and give
each one a support status: <span class="ac-live">live</span> means implemented and doing the
work, while <span class="ac-no">stub</span> means present for source compatibility but returning
success without performing the named function.
</p><h6>File operations</h6><div class="table-wrapper"><table><thead><tr><th>SYS$ routine</th><th>EXE$ variant</th><th>Purpose</th><th>Status</th></tr></thead><tbody><tr><td><code>SYS$OPEN</code></td><td><code>EXE$OPEN</code></td><td>Open an existing file; organization is auto-sniffed from disk.</td><td><span class="ac-live">live</span></td></tr><tr><td><code>SYS$CREATE</code></td><td><code>EXE$CREATE</code></td><td>Create an indexed, relative, or sequential file; build keys, write the file header, resolve version.</td><td><span class="ac-live">live</span></td></tr><tr><td><code>SYS$CLOSE</code></td><td><code>EXE$CLOSE</code></td><td>Close a file, including delete-on-close and revision-date write.</td><td><span class="ac-live">live</span></td></tr><tr><td><code>SYS$ERASE</code></td><td><code>EXE$ERASE</code></td><td>Delete a file, including wildcard erase via a parse, search, and unlink loop.</td><td><span class="ac-live">live</span></td></tr><tr><td><code>SYS$RENAME</code></td><td><code>EXE$RENAME</code></td><td>Rename a file (implemented as link then unlink, not an atomic rename).</td><td><span class="ac-live">live</span></td></tr><tr><td><code>SYS$COPY</code></td><td><code>EXE$COPY</code></td><td>Copy a file by opening, creating, and streaming raw chunks.</td><td><span class="ac-live">live</span></td></tr><tr><td><code>SYS$DISPLAY</code></td><td><code>EXE$DISPLAY</code></td><td>Fill FAB, NAM, and XAB output fields from the file on disk.</td><td><span class="ac-live">live</span></td></tr><tr><td><code>SYS$PARSE</code></td><td><code>EXE$PARSE</code></td><td>Parse a filename, translate logical names, and build the wildcard chain.</td><td><span class="ac-live">live</span></td></tr><tr><td><code>SYS$SEARCH</code></td><td><code>EXE$SEARCH</code></td><td>Return the next wildcard match.</td><td><span class="ac-live">live</span></td></tr><tr><td><code>SYS$FREELIST</code></td><td>none</td><td>Free the internal parse and search directory chain.</td><td><span class="ac-live">live</span></td></tr></tbody></table></div><h6>Record operations</h6><div class="table-wrapper"><table><thead><tr><th>SYS$ routine</th><th>EXE$ variant</th><th>Purpose</th><th>Status</th></tr></thead><tbody><tr><td><code>SYS$CONNECT</code></td><td><code>EXE$CONNECT</code></td><td>Attach a record stream to an open file and position by key.</td><td><span class="ac-live">live</span></td></tr><tr><td><code>SYS$DISCONNECT</code></td><td><code>EXE$DISCONNECT</code></td><td>Detach a record stream.</td><td><span class="ac-live">live</span></td></tr><tr><td><code>SYS$GET</code></td><td><code>EXE$GET</code></td><td>Read a record (multi-way dispatch across organizations, plus terminal and mailbox paths).</td><td><span class="ac-live">live</span></td></tr><tr><td><code>SYS$PUT</code></td><td><code>EXE$PUT</code></td><td>Write a record (multi-way dispatch across organizations).</td><td><span class="ac-live">live</span></td></tr><tr><td><code>SYS$FIND</code></td><td><code>EXE$FIND</code></td><td>Position to a record without transferring it.</td><td><span class="ac-live">live</span></td></tr><tr><td><code>SYS$UPDATE</code></td><td><code>EXE$UPDATE</code></td><td>Rewrite the current record.</td><td><span class="ac-live">live</span></td></tr><tr><td><code>SYS$DELETE</code></td><td><code>EXE$DELETE</code></td><td>Delete the current record (indexed and relative organizations).</td><td><span class="ac-live">live</span></td></tr><tr><td><code>SYS$READ</code></td><td><code>EXE$READ</code></td><td>Block-level (virtual block number) read.</td><td><span class="ac-live">live</span></td></tr><tr><td><code>SYS$WRITE</code></td><td><code>EXE$WRITE</code></td><td>Block-level write.</td><td><span class="ac-live">live</span></td></tr><tr><td><code>SYS$TRUNCATE</code></td><td><code>EXE$TRUNCATE</code></td><td>Truncate a sequential file at the current record.</td><td><span class="ac-live">live</span></td></tr><tr><td><code>SYS$REWIND</code></td><td><code>EXE$REWIND</code></td><td>Reposition the stream to the first record.</td><td><span class="ac-live">live</span></td></tr><tr><td><code>SYS$FLUSH</code></td><td><code>EXE$FLUSH</code></td><td>Force buffered output to disk.</td><td><span class="ac-live">live</span></td></tr></tbody></table></div><h6>Locking</h6><div class="table-wrapper"><table><thead><tr><th>SYS$ routine</th><th>EXE$ variant</th><th>Purpose</th><th>Status</th></tr></thead><tbody><tr><td><code>SYS$FREE</code></td><td><code>EXE$FREE</code></td><td>Release all record locks held on the stream.</td><td><span class="ac-live">live</span></td></tr><tr><td><code>SYS$RELEASE</code></td><td><code>EXE$RELEASE</code></td><td>Release the lock on the current record only.</td><td><span class="ac-live">live</span></td></tr></tbody></table></div><h6>Stubs (accepted for source compatibility)</h6><div class="table-wrapper"><table><thead><tr><th>SYS$ routine</th><th>Purpose on VMS</th><th>Status</th></tr></thead><tbody><tr><td><code>SYS$EXTEND</code></td><td>Extend a file's allocation.</td><td><span class="ac-no">stub: the host file system extends on demand</span></td></tr><tr><td><code>SYS$WAIT</code></td><td>Wait for asynchronous completion.</td><td><span class="ac-no">stub: all I/O is synchronous</span></td></tr><tr><td><code>SYS$START_RU</code></td><td>Begin a recovery unit.</td><td><span class="ac-no">stub: journalling not implemented</span></td></tr><tr><td><code>SYS$END_RU</code></td><td>End a recovery unit.</td><td><span class="ac-no">stub</span></td></tr><tr><td><code>SYS$ABORT_RU</code></td><td>Abort a recovery unit.</td><td><span class="ac-no">stub</span></td></tr></tbody></table></div><div class="callout"><strong>Full surface, honest boundaries.</strong> VX/RMS exports the complete set of SYS$
entry points so existing code links cleanly. The record and file services are live; the five
stubs above return success without acting, which matches how their functions behave under a
host file system where allocation, asynchronous I/O, and RMS journalling are handled
differently.
</div><h2 id="status-mapping">Status codes and error mapping</h2><p>
Applications that inspect RMS status values keep working unchanged, because VX/RMS returns the
same VMS-style condition codes and maps native host error numbers back to their RMS equivalents.
Status symbols are written <code>RMS$_XXX</code> in VMS notation. A representative set of the
common codes:
</p><div class="table-wrapper"><table><thead><tr><th>Symbol</th><th>Decimal</th><th>Meaning</th></tr></thead><tbody><tr><td><code>RMS$_NORMAL</code></td><td>65537</td><td>Successful completion.</td></tr><tr><td><code>RMS$_EOF</code></td><td>98938</td><td>End of file.</td></tr><tr><td><code>RMS$_FNF</code></td><td>98962</td><td>File not found.</td></tr><tr><td><code>RMS$_RLK</code></td><td>98986</td><td>Record is locked.</td></tr><tr><td><code>RMS$_OK_RLK</code></td><td>98337</td><td>Success, but the record was already locked.</td></tr></tbody></table></div><h6>Host errno to RMS status</h6><p>
When a host system call fails, VX/RMS translates the <code>errno</code> value into the matching
RMS condition code, sets <code>RMS_STATUS</code>, and returns it. This is the mechanism behind
automatic error-code mapping:
</p><div class="table-wrapper"><table><thead><tr><th>Host errno</th><th>RMS status</th><th>Meaning</th></tr></thead><tbody><tr><td><code>ENOENT</code></td><td><code>RMS$_FNF</code></td><td>File not found.</td></tr><tr><td><code>EAGAIN</code></td><td><code>RMS$_RLK</code></td><td>Record locked by another stream.</td></tr><tr><td><code>ENOSPC</code></td><td><code>RMS$_FUL</code></td><td>Device or file full.</td></tr><tr><td><code>EACCES</code></td><td><code>RMS$_PRV</code></td><td>Privilege or protection violation.</td></tr></tbody></table></div><p>
Because the status is returned by value and also mirrored in the global <code>RMS_STATUS</code>,
existing patterns such as testing <code>ODD(status)</code> or comparing against
<code>RMS$_EOF</code> at the end of a read loop behave exactly as they did on VMS.
</p><h2 id="compatibility">Compatibility with native OpenVMS RMS</h2><p>
VX/RMS covers the record and file services that production applications actually depend on, and
is explicit about the areas that behave differently on a host file system. The matrix below
places each capability in exactly one bucket.
</p><div class="table-wrapper"><table><thead><tr><th>Capability</th><th>Status</th><th>Note</th></tr></thead><tbody><tr><td>Sequential, relative, and indexed record I/O</td><td><span class="ac-live">live</span></td><td>Full open, get, put, update, delete, and find.</td></tr><tr><td>Filename parse, logical-name translation, wildcard search</td><td><span class="ac-live">live</span></td><td>Handled by the parse and search services.</td></tr><tr><td>File-level operations (create, erase, rename, copy)</td><td><span class="ac-live">live</span></td><td>Rename is link-then-unlink, not an atomic operation.</td></tr><tr><td>Record and file locking</td><td><span class="ac-live">live</span></td><td>D-ISAM record locks for indexed; byte-range locks for sequential and relative.</td></tr><tr><td>Version emulation</td><td><span class="ac-live">live</span></td><td>Next version on create, highest version on open.</td></tr><tr><td>Keyed indexed files with secondary keys</td><td><span class="ac-live">live</span></td><td>Primary and multiple secondary keys with various key types.</td></tr><tr><td>AST asynchronous callbacks</td><td><span class="ac-v1">partial</span></td><td>Gated by the <code>RMSAST</code> option, which is off by default.</td></tr><tr><td>Multi-stream sharing bit</td><td><span class="ac-v1">partial</span></td><td>Sharing is taken from the share field rather than the multi-stream bit.</td></tr><tr><td>Asynchronous I/O</td><td><span class="ac-no">out of scope</span></td><td>Accepted but I/O blocks; the wait service is a no-op stub.</td></tr><tr><td>Recovery-unit and transaction journalling</td><td><span class="ac-no">out of scope</span></td><td>Attribute blocks are recognised so parsing succeeds, but the feature is inert.</td></tr><tr><td>File pre-allocation (extend)</td><td><span class="ac-no">out of scope</span></td><td>Stub; the host file system extends on demand.</td></tr><tr><td>Magnetic tape and print-spool bits</td><td><span class="ac-no">out of scope</span></td><td>Accepted with no behaviour.</td></tr></tbody></table></div><h6>Deliberate divergences from native RMS</h6><p>These are behaviours that differ by design because the storage layer is a host file system:</p><ul><li><strong>Storage layer.</strong> Sequential and relative files are plain host files; indexed files use a D-ISAM keyed store. Relative records carry a small VMS-shaped header, and an optional 44-byte file-header block records the record attributes.</li><li><strong>No signals.</strong> Every error is returned by value; VMS condition handlers never fire.</li><li><strong>Synchronous I/O.</strong> AST callbacks may fire, but the I/O itself blocks and the wait service returns immediately.</li><li><strong>Rename is link-then-unlink.</strong> A crash mid-operation can leave the source under the new name with the old name dangling.</li><li><strong>File identifiers.</strong> Directory and file identifiers hold host inode numbers, which are stable on the running host but are not portable VMS file identifiers.</li><li><strong>Threading.</strong> The process-global status makes RMS non-reentrant across threads.</li></ul><h2 id="fdl">FDL file definition tooling</h2><p>
VX/RMS ships call-compatible File Definition Language (FDL) support, so the utilities and
callable routines that describe and analyse RMS file structure carry over to the migrated
environment. FDL definitions continue to drive file creation and tuning without change.
</p><div class="table-wrapper"><table><thead><tr><th>Routine or utility</th><th>Purpose</th></tr></thead><tbody><tr><td><code>CREATE/FDL</code></td><td>Create an RMS file from an FDL definition.</td></tr><tr><td><code>ANALYZE/FDL</code></td><td>Analyse an existing file and report its FDL attributes.</td></tr><tr><td><code>FDL$CREATE</code></td><td>Callable routine to create a file from an in-memory FDL specification.</td></tr><tr><td><code>FDL$GENERATE</code></td><td>Generate an FDL description from a file's attributes.</td></tr><tr><td><code>FDL$PARSE</code></td><td>Parse an FDL specification into internal descriptors.</td></tr><tr><td><code>FDL$RELEASE</code></td><td>Release descriptors allocated by a prior parse.</td></tr></tbody></table></div><p>
For the standalone FDL routine set and the broader file-conversion tooling, see
<a href="/technical/vx-fdl-file-description-language-routines">VX/FDL File Description Language Routines</a>,
<a href="/technical/api-fdl-file-definition-language">the FDL$ File Definition Language API</a>, and
<a href="/technical/api-conv-file-conversion">CONV$ File Conversion</a>.
</p><h2 id="quickref">Quick reference</h2><h6>SYS$ routines</h6><div class="kw-grid"><div>SYS$OPEN</div><div>SYS$CREATE</div><div>SYS$CLOSE</div><div>SYS$CONNECT</div><div>SYS$DISCONNECT</div><div>SYS$GET</div><div>SYS$PUT</div><div>SYS$FIND</div><div>SYS$UPDATE</div><div>SYS$DELETE</div><div>SYS$READ</div><div>SYS$WRITE</div><div>SYS$TRUNCATE</div><div>SYS$REWIND</div><div>SYS$FLUSH</div><div>SYS$FREE</div><div>SYS$RELEASE</div><div>SYS$DISPLAY</div><div>SYS$PARSE</div><div>SYS$SEARCH</div><div>SYS$FREELIST</div><div>SYS$ERASE</div><div>SYS$RENAME</div><div>SYS$COPY</div></div><h6>FDL routines and utilities</h6><div class="kw-grid"><div>CREATE/FDL</div><div>ANALYZE/FDL</div><div>FDL$CREATE</div><div>FDL$GENERATE</div><div>FDL$PARSE</div><div>FDL$RELEASE</div></div><h6>Control blocks</h6><div class="kw-grid"><div>FAB</div><div>RAB</div><div>XAB</div><div>NAM</div></div><h6>Organizations and access modes</h6><div class="kw-grid"><div>Sequential</div><div>Relative</div><div>Indexed</div><div>Sequential access</div><div>Keyed access</div><div>Record-file-address access</div></div><h6>Configuration options</h6><div class="kw-grid"><div>RMSAST</div><div>IGNORE_FHC</div><div>NOFHC</div><div>EXTUNIX</div><div>UCMAP</div></div><h6>Open, read, close skeleton</h6><p>
A migrated program links this unchanged against <code>libvxrt.a</code>. Note the
<code>ODD()</code> status test after each call and the record buffer passed by reference:
</p>
<pre><span class="cmt">// open the file and connect a record stream</span>
status = SYS$OPEN(fab); <span class="cmt">// fab names BANKING:[ACCOUNTS]CUSTOMER.DAT</span>
<span class="kw">if</span> (!ODD(status)) <span class="kw">goto</span> fail;
status = SYS$CONNECT(rab);
<span class="kw">if</span> (!ODD(status)) <span class="kw">goto</span> fail;
<span class="cmt">// read records until end of file</span>
<span class="kw">while</span> (ODD(status = SYS$GET(rab))) {
process_record(rab->RAB$L_UBF); <span class="cmt">// application record buffer, filled by RMS</span>
}
<span class="kw">if</span> (status != RMS$_EOF) <span class="kw">goto</span> fail;
<span class="cmt">// tear down</span>
SYS$DISCONNECT(rab);
SYS$CLOSE(fab);</pre>
<h6>Related pages</h6><ul><li><a href="/technical/vx-datax-vms-rms-data-exchange">VX/DATAX OpenVMS RMS Data Exchange</a> for moving RMS data between VMS and the target host.</li><li><a href="/technical/vx-lckmgr-vms-openvms-lock-manager-for-x86-intel-linux">VX/LCKMGR OpenVMS Lock Manager</a> for the underlying locking services.</li><li><a href="/technical/api-sys-interface-routines">SYS$ Interface Routines</a> and <a href="/technical/api-exe-operating-system-interface">EXE$ Operating System Interface</a> for the broader system-service surface.</li><li><a href="/technical/api-sor-interface-to-sort">SOR$ Interface to SORT</a> for sorting and merging RMS files.</li></ul></div>