🚨 Oracle not porting Rdb to x86 and EOL on Itanium 12/2027 🚨
Technical Capabilities
Having trouble finding what you need?
Get in touch with us, so we can answer your specific questions directly.
Get In Touch

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 &amp;&amp; ODD(rc)) (*success)(); <span class="kw">else if</span> (error &amp;&amp; !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-&gt;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>

Frequently Asked Questions

Curious about how Sector7 can facilitate your application migration? Explore our FAQs for expert insights.

What is VX/RMS and how does it help with VMS migration?

VX/RMS is a call-compatible library that enables seamless migration of VMS/OpenVMS RMS applications to Linux without requiring any source code changes. It provides complete support for all VMS file types, access modes, record formats, and file locking mechanisms.

By implementing the SYS$ API set, VX/RMS ensures your applications function identically on Linux as they did on VMS/OpenVMS, eliminating the need for extensive rewrites. To discuss your specific migration requirements, contact us.

Which VMS file types does VX/RMS support?

VX/RMS supports all VMS/OpenVMS RMS file types including Indexed, Relative, Sequential, and Block mode files with full compatibility.

What SYS$ API functions are supported by VX/RMS?

VX/RMS implements all essential SYS$ API calls including SYS$OPEN, SYS$GET, SYS$PUT, SYS$READ, SYS$WRITE, SYS$UPDATE, SYS$SEARCH, SYS$PARSE, and SYS$RENAME among others.

How does VX/RMS handle file and record locking?

VX/RMS retains VMS/OpenVMS record-locking mechanisms while supporting enhanced Linux locking standards, ensuring data integrity and concurrent access control.

How does VX/RMS handle VMS file specifications and logical names?

VX/RMS automatically translates VMS-style file paths and logicals into Linux equivalents, maintaining application compatibility without manual intervention.

What FDL functions are supported by VX/RMS?

VX/RMS includes call-compatible FDL libraries supporting ANALYZE/FDL, CREATE/FDL, FDL$CREATE, FDL$GENERATE, FDL$PARSE, and FDL$RELEASE functions for complete file definition compatibility.

Do I need to change my application source code to migrate RMS with VX/RMS?

No. VX/RMS is a call-compatible library, so OpenVMS RMS applications move to Linux and Windows without source code changes. It presents the same SYS$ API and file behaviour, so existing programs open, read, write, and lock records exactly as they did on VMS.

Which RMS file organizations does VX/RMS support?

All OpenVMS RMS file organizations: indexed, relative, and sequential, along with their associated access modes and record formats. Sequential and relative files map onto plain host files, and indexed files use a keyed store.

Does VX/RMS preserve VMS record and file locking?

Yes. It retains the OpenVMS record-locking behaviour and applies host byte-range locks for sequential and relative files and record locks for indexed files, so concurrent-access behaviour is maintained after migration.

How are VMS file specifications and logical names handled after migration?

VX/RMS parses VMS-style file specifications and translates logical names into their host equivalents automatically, so applications keep using VMS file specs without manual path rewriting.

What happens to RMS error codes when my application runs on Linux?

VX/RMS maps native host error numbers back to their corresponding VMS RMS status values. For example, a host file-not-found error becomes RMS$_FNF, so code that inspects RMS status values continues to behave as it did on VMS.

Which SYS$ routines does VX/RMS implement?

VX/RMS implements the OpenVMS RMS callable services, including SYS$OPEN, SYS$CREATE, SYS$CLOSE, SYS$CONNECT, SYS$GET, SYS$PUT, SYS$FIND, SYS$UPDATE, SYS$DELETE, SYS$PARSE, and SYS$SEARCH, each with an EXE$ inner variant and Fortran-compatible aliases.

Does VX/RMS support FDL file definition tooling?

Yes. VX/RMS provides call-compatible FDL support, including CREATE/FDL, ANALYZE/FDL, and the FDL$CREATE, FDL$GENERATE, FDL$PARSE, and FDL$RELEASE routines, so FDL-based file definition and analysis carry over to the migrated environment.

What is VX/RMS and how does it help with OpenVMS migration?

VX/RMS is a call-compatible library that runs OpenVMS RMS applications on Linux and Windows without source code changes. It supports all RMS file types, access modes, record formats, and locking, and implements the SYS$ API, so applications keep working on a modern platform with no rewrite.

Transform Your Legacy Software Today!

Get In Touch
Unlock the potential of your legacy software with our expert migration services.