CONV$ - File Conversion
Overview
VX/CONV$ is a call-compatible reimplementation of the OpenVMS CONVERT/FDL callable interface for x86 and ARM Linux. It is the CONV$ routine family that OpenVMS applications use to copy records from one file into another whose organization and attributes come from an FDL (File Definition Language) description. Existing calls to CONV$PASS_FILES, CONV$PASS_OPTIONS, CONV$CONVERT, and CONV$RECLAIM link and run without source changes.
It is not a standalone daemon or a compiler: the callable surface is a small set of C-linkage entry points compiled into the shared VX runtime and driven by a three-call state machine. VX/CONV$ runs inside the VX/RT ecosystem, building output files from FDL definitions, reading and writing records through the VX/RMS runtime, and preserving data integrity by padding, truncating, or reporting records rather than silently corrupting them when file layouts differ.
<!-- Webflow embed (min). Source: conv-page-technical/conv-tech-body-embed-dark.html → python3 website/embeds/minify_webflow_embed.py … -->
<div class="s7-tech-embed" data-vxconvd-body-embed="1" data-technical-mega-embed="1" lang="en"><h2 id="architecture">Architecture and components</h2><p>
VX/CONV$ is a library, not a server. There is no daemon to administer and no separate
<code>conv</code> binary: the entire callable surface compiles into the shared VX runtime
archive (<code>libvxrt.a</code>) and is driven directly by the migrated application. Because
CONV$ is a library, its "components" are the four exported entry points plus the RMS and FDL
runtimes they delegate to.
</p><div class="table-wrapper"><table><thead><tr><th>OpenVMS routine</th><th>Role</th><th>Status</th></tr></thead><tbody><tr><td><code>CONV$PASS_FILES</code></td><td>Queue the input file(s), the output file, an optional FDL, and an optional exception file; advance the state machine to the options stage.</td><td><span class="ac-live">live</span></td></tr><tr><td><code>CONV$PASS_OPTIONS</code></td><td>Load the option vector, apply defaults, and reject conflicting qualifiers; advance the state machine to the convert stage.</td><td><span class="ac-live">live</span></td></tr><tr><td><code>CONV$CONVERT</code></td><td>Run the conversion, fill the caller's statistics block, and reset the state machine to the files stage.</td><td><span class="ac-live">live</span></td></tr><tr><td><code>CONV$RECLAIM</code></td><td>Report file allocation statistics. On OpenVMS this reclaims empty index buckets; on Linux it reports allocation only (see the compatibility section).</td><td><span class="ac-v1">partial</span></td></tr></tbody></table></div><div class="callout"><strong>No server to administer.</strong> There is no process to start, no configuration
file, and no IPC substrate. Applications link the VX runtime and call the <code>CONV$</code>
entry points directly, exactly as they did on OpenVMS.
</div><h6>Runtime dependencies</h6><p>
The conversion routines delegate the real work to the rest of the VX/RT toolset. This is why
VX/CONV$ slots into a full OpenVMS-compatible estate rather than working in isolation.
</p><div class="table-wrapper"><table><thead><tr><th>Dependency</th><th>What CONV$ uses it for</th></tr></thead><tbody><tr><td>VX/RMS (<code>SYS$</code> services)</td><td>Open, create, connect, get, put, close, and disconnect on FAB, RAB, and XAB control blocks for every input and output file.</td></tr><tr><td>VX/FDL (<code>FDL$CREATE</code>)</td><td>Build the output file from an FDL definition when the FDL option is set.</td></tr><tr><td>VX/SORT options</td><td>Shares the sort, merge, and work-file option encoding with the SORT interface.</td></tr><tr><td>STR$ / LIB$ routines</td><td>Marshal filename descriptors and probe for file existence.</td></tr><tr><td>Indexed-file layer (D-ISAM)</td><td>Handle indexed (IDX) organizations and erase existing relative and sequential output.</td></tr></tbody></table></div><h6>Component map</h6><style>.s7-tech-embed .conv-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 .conv-flow-node {min-width: 0;padding: 14px 16px;border-radius: 8px;background: var(--s7t-surface);color: var(--s7t-text);}.s7-tech-embed .conv-flow-node strong,.s7-tech-embed .conv-flow-node span {display: block;}.s7-tech-embed .conv-flow-node strong {margin-bottom: 4px;}.s7-tech-embed .conv-flow-node span {color: var(--s7t-muted);font-size: 0.9em;line-height: 1.45;}.s7-tech-embed .conv-flow-stage {border-top: 3px solid var(--s7t-accent);background: var(--s7t-surface2);}.s7-tech-embed .conv-flow-output {border: 1px solid var(--s7t-note-bd);background: var(--s7t-note-bg);}.s7-tech-embed .conv-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 .conv-flow-branches,.s7-tech-embed .conv-flow-sequence,.s7-tech-embed .conv-flow-outcomes {display: grid;gap: 10px;}.s7-tech-embed .conv-flow-branches,.s7-tech-embed .conv-flow-outcomes {grid-template-columns: repeat(3, minmax(0, 1fr));}.s7-tech-embed .conv-flow-sequence {grid-template-columns: repeat(3, minmax(0, 1fr));}.s7-tech-embed .conv-flow-reset,.s7-tech-embed .conv-flow-error {margin-top: 10px;padding: 12px 14px;border-radius: 8px;color: var(--s7t-muted);font-size: 0.9em;line-height: 1.45;}.s7-tech-embed .conv-flow-reset {border: 1px dashed var(--s7t-border);}.s7-tech-embed .conv-flow-error {border: 1px solid var(--s7t-warn-bd);background: var(--s7t-warn-bg);}@media (max-width: 800px) {.s7-tech-embed .conv-flow-branches,.s7-tech-embed .conv-flow-sequence,.s7-tech-embed .conv-flow-outcomes {grid-template-columns: 1fr;}}</style><div class="conv-flow" aria-label="VX/CONV application, runtime dependencies, and output topology"><div class="conv-flow-node"><strong>Application</strong><span>Calls the <code>CONV$</code> entry points</span></div><div class="conv-flow-label">Delegates through</div><div class="conv-flow-node conv-flow-stage"><strong><code>libvxrt.a</code></strong><span><code>CONV$</code> entry points coordinate the conversion</span></div><div class="conv-flow-label">Uses three runtime branches</div><div class="conv-flow-branches"><div class="conv-flow-node conv-flow-stage"><strong>VX/FDL create</strong><span><code>FDL$CREATE</code> builds an FDL-defined output</span></div><div class="conv-flow-node conv-flow-stage"><strong>VX/RMS record I/O</strong><span><code>SYS$OPEN</code>, <code>GET</code>, <code>PUT</code>, and <code>CLOSE</code></span></div><div class="conv-flow-node conv-flow-stage"><strong>Indexed-file layer</strong><span>IDX open and erase operations</span></div></div><div class="conv-flow-label">Branches converge</div><div class="conv-flow-node conv-flow-output"><strong>Output file built and records copied</strong><span>The selected dependencies create, populate, and finalize the output</span></div></div><h2 id="call-lifecycle">The call lifecycle</h2><p>
VX/CONV$ is a three-stage state machine. Each routine checks that it is being called in the
right stage and, on a mismatch, resets the sequence to the start and returns an order status
(<code>CONV$_ORDER</code>). The required order is <code>PASS_FILES</code>, then
<code>PASS_OPTIONS</code>, then <code>CONVERT</code>.
</p><div class="conv-flow" aria-label="VX/CONV three-stage call lifecycle and reset paths"><div class="conv-flow-sequence"><div class="conv-flow-node conv-flow-stage"><strong>1. <code>PASS_FILES</code></strong><span>Queue input files, output file, FDL, and exception file</span></div><div class="conv-flow-node conv-flow-stage"><strong>2. <code>PASS_OPTIONS</code></strong><span>Load defaults, apply options, and validate conflicts</span></div><div class="conv-flow-node conv-flow-stage"><strong>3. <code>CONVERT</code></strong><span>Copy records and write the statistics block</span></div></div><div class="conv-flow-reset"><strong>Normal reset loop:</strong> after each successful conversion, the sequence returns
to <code>PASS_FILES</code> for the next run.
</div><div class="conv-flow-error"><strong>Wrong-order reset:</strong> a call made at the wrong stage returns
<code>CONV$_ORDER</code> and resets the sequence to <code>PASS_FILES</code>.
</div></div><h6>Stage 1: pass files</h6><p>
Call <code>CONV$PASS_FILES</code> once per input file. The first call that carries an output
name resets the input list and saves the output file and the optional FDL; subsequent calls
with no output name append further input files, up to a maximum of <strong>10</strong>. No
input file returns <code>CONV$_NARG</code>; overflowing the input limit returns
<code>CONV$_INP_FILES</code>. On success the stage advances to options.
</p><h6>Stage 2: pass options</h6><p><code>CONV$PASS_OPTIONS</code> loads the defaults, overlays the caller's option list,
validates it, and advances the stage to convert. Conflicting qualifiers are rejected here
before any file is touched (see the options section).
</p><h6>Stage 3: convert</h6><p><code>CONV$CONVERT</code> performs the copy, writes the statistics back into the caller's
block, and resets the stage to files so the next conversion starts cleanly.
</p><div class="callout warn"><strong>Single, process-global context.</strong> The stage, the option vector, the
statistics, and the file control blocks are module-level state shared across the process,
matching the single-context OpenVMS callable interface. Concurrent conversions on separate
threads share that state, so run conversions sequentially rather than in parallel within a
process.
</div><h2 id="options">Conversion options</h2><p><code>CONV$PASS_OPTIONS</code> takes a counted array: the first element is the number of
option words that follow, and the remaining elements populate a 19-slot option vector. The
named slots are:
</p><div class="table-wrapper"><table><thead><tr><th>Index</th><th>Option</th><th>Index</th><th>Option</th><th>Index</th><th>Option</th></tr></thead><tbody><tr><td>0</td><td><code>create</code></td><td>7</td><td><code>key</code></td><td>14</td><td><code>read_check</code></td></tr><tr><td>1</td><td><code>share</code></td><td>8</td><td><code>pad</code></td><td>15</td><td><code>write_check</code></td></tr><tr><td>2</td><td><code>fast_load</code></td><td>9</td><td><code>padchar</code></td><td>16</td><td><code>fdl</code></td></tr><tr><td>3</td><td><code>merge</code></td><td>10</td><td><code>truncate</code></td><td>17</td><td><code>exception</code></td></tr><tr><td>4</td><td><code>append</code></td><td>11</td><td><code>exit</code></td><td>18</td><td><code>prolog</code></td></tr><tr><td>5</td><td><code>sort</code></td><td>12</td><td><code>fixed_control</code></td><td></td><td></td></tr><tr><td>6</td><td><code>work_files</code></td><td>13</td><td><code>fill_buckets</code></td><td></td><td></td></tr></tbody></table></div><h6>Defaults</h6><p>
Before the caller's list is overlaid, the vector is zeroed and then these defaults are
applied: <code>create = 1</code>, <code>fast_load = 1</code>, <code>sort = 1</code>, and
<code>work_files = 2</code>. All other slots default to zero.
</p><h6>Consistency check</h6><p><code>CONV$PASS_OPTIONS</code> rejects contradictory requests up front with
<code>CONV$_CONFQUAL</code> ("conflicting qualifiers") in any of these cases:
</p><ul><li>An FDL filename was passed, but the <code>fdl</code> option is not set.</li><li>The <code>fdl</code> option is set while <code>create</code> is clear.</li><li>Both <code>pad</code> and <code>truncate</code> are set.</li></ul><div class="callout"><strong>Which options change behaviour today.</strong> On the current Linux conversion
path, the options that alter the conversion are <code>fdl</code>, <code>pad</code>,
<code>padchar</code>, and <code>truncate</code>. The remaining slots (share, merge, append,
sort, key, work_files, fixed_control, fill_buckets, read_check, write_check, exception,
prolog, exit) are accepted and stored for call compatibility so existing option vectors pass
through unchanged. Confirm the exact option encoding against the CONV$ API reference before
relying on a specific option's effect.
</div><h2 id="convert">The convert path and record integrity</h2><p><code>CONV$CONVERT</code> runs a top-level loop that creates the output file, then opens each
input file in turn and copies its records into the output. The output can be local or on a
remote node.
</p><h6>How the output file is created</h6><ul><li>When the <code>fdl</code> option is set, the output file is built first from the FDL
definition through <code>FDL$CREATE</code>, giving the output an explicit organization and
attributes.</li><li>When there is no FDL, the output organization defaults to the input's own organization,
so the conversion copies attributes rather than reformatting. Any pre-existing output is
removed first: indexed files are unlinked, and relative or sequential files are erased
through the indexed-file layer.</li><li>If the output resolves to a remote node, the copy is handled with an SSH-based transport,
with network failures mapped back to RMS status values (for example an SSH transport failure
maps to <code>RMS$_NETFAIL</code>).</li></ul><h6>Record-size policy</h6><p>
The record copy loop is where the "preserves data integrity" guarantee actually lives. For
each record read from the input, VX/CONV$ compares the input and output maximum record sizes
and applies one of three policies:
</p><div class="table-wrapper"><table><thead><tr><th>Case</th><th>Behaviour</th><th>Result</th></tr></thead><tbody><tr><td>Sizes equal</td><td>Copy the record verbatim.</td><td><span class="ac-live">copied</span></td></tr><tr><td>Input longer than output</td><td>If <code>truncate</code> is set, shrink to the output size; otherwise reject the record.</td><td>truncated, or <code>CONV$_RTL</code> (record too long)</td></tr><tr><td>Input shorter than output</td><td>If <code>pad</code> is set, pad with <code>padchar</code> to the output size; otherwise reject the record.</td><td>padded, or <code>CONV$_RTS</code> (record too short)</td></tr></tbody></table></div><p>
A record that cannot be safely resized is <strong>counted as an exception rather than
silently corrupted</strong>. The routine returns a record-too-long or record-too-short status,
and the exception count is reported back in the statistics block. This is the substance behind
the product's data-integrity claim: records are either copied faithfully, resized under an
explicit option, or flagged, never truncated by accident.
</p><div class="conv-flow" aria-label="VX/CONV record-size decisions and outcomes"><div class="conv-flow-node"><strong>Read one input record</strong><span>Use RMS <code>GET</code>, then compare input and output maximum record sizes</span></div><div class="conv-flow-label">Choose one size policy</div><div class="conv-flow-outcomes"><div class="conv-flow-node conv-flow-stage"><strong>Sizes match</strong><span>Copy the record verbatim</span></div><div class="conv-flow-node conv-flow-stage"><strong>Input is longer</strong><span>Truncate only when allowed, otherwise count a <code>CONV$_RTL</code> exception</span></div><div class="conv-flow-node conv-flow-stage"><strong>Input is shorter</strong><span>Pad with <code>padchar</code> only when allowed, otherwise count a <code>CONV$_RTS</code> exception</span></div></div><div class="conv-flow-label">All outcomes continue</div><div class="conv-flow-node conv-flow-output"><strong>Write or flag the record</strong><span>Use RMS <code>PUT</code> for accepted records, then continue until end-of-file</span></div><div class="conv-flow-reset"><strong>Final report:</strong> files processed, records handled, exceptions counted, and
validity status.
</div></div><h2 id="api">Callable routines and linkage</h2><p>
The four <code>CONV$</code> routines are exported under both their upper-case
(<code>CONV$...</code>) and lower-case (<code>conv$...</code>) names, so existing object
references resolve unchanged. Each routine returns an OpenVMS condition value by value: odd
means success, even means failure.
</p><div class="table-wrapper"><table><thead><tr><th>CONV$ routine</th><th>Function</th></tr></thead><tbody><tr><td><code>CONV$CONVERT</code></td><td>Convert data format</td></tr><tr><td><code>CONV$PASS_FILES</code></td><td>Pass files for conversion</td></tr><tr><td><code>CONV$PASS_OPTIONS</code></td><td>Pass conversion options</td></tr><tr><td><code>CONV$RECLAIM</code></td><td>Reclaim conversion resources</td></tr></tbody></table></div><h6>Signatures</h6>
<pre>U32 <span class="kw">CONV$PASS_FILES</span> (VMS_DESCR *Ifil, VMS_DESCR *Ofil, VMS_DESCR *Fdl,
VMS_DESCR *Exc, U32 *flags);
U32 <span class="kw">CONV$PASS_OPTIONS</span>(U32 *plist, U32 *flags);
U32 <span class="kw">CONV$CONVERT</span> (U32 *statblock, U32 *flags);
U32 <span class="kw">CONV$RECLAIM</span> (VMS_DESCR *InFile, U32 Stats[]);</pre>
<h6>FORTRAN and external linkage</h6><p>
Each routine also has a FORTRAN-descriptor wrapper that trims blank-padded FORTRAN strings
before calling the C entry point, so applications written in FORTRAN as well as C, Pascal, and
other OpenVMS languages call the same names. This is what makes migration a link-and-run
exercise rather than a rewrite.
</p><h6>Statistics blocks</h6><p><code>CONV$CONVERT</code> writes back a counted statistics array in the same shape the options
are read: if the caller supplies a block and a count, that many words are copied from the
four internal results.
</p><div class="table-wrapper"><table><thead><tr><th>Slot</th><th>Statistic</th></tr></thead><tbody><tr><td>0</td><td>Number of files converted</td></tr><tr><td>1</td><td>Number of records read</td></tr><tr><td>2</td><td>Number of exception records</td></tr><tr><td>3</td><td>Number of valid records written</td></tr></tbody></table></div><p><code>CONV$RECLAIM</code> fills a separate statistics array, reporting the file allocation in
512-byte blocks.
</p><h2 id="compatibility">Compatibility and status</h2><p>
The table below is the honest coverage matrix for the current Linux implementation: what runs
today, what is accepted for compatibility but not yet fully wired, and what is out of scope.
</p><div class="table-wrapper"><table><thead><tr><th>Capability</th><th>Status</th></tr></thead><tbody><tr><td>Files state machine and multi-input queue (up to 10 inputs), FDL and output capture</td><td><span class="ac-live">live</span></td></tr><tr><td>Options defaults and conflict checks (pad/truncate, fdl/create)</td><td><span class="ac-live">live</span></td></tr><tr><td>Local copy for sequential, relative, and indexed output through RMS and FDL, with statistics writeback</td><td><span class="ac-live">live</span></td></tr><tr><td>Record pad and truncate with pad character, and exception counting</td><td><span class="ac-live">live</span></td></tr><tr><td>Remote-node output copy over SSH transport</td><td><span class="ac-live">live</span></td></tr><tr><td>Option slots beyond fdl, pad, padchar, and truncate</td><td><span class="ac-v1">partial: accepted and stored, not consumed on the current path</span></td></tr><tr><td><code>CONV$RECLAIM</code></td><td><span class="ac-v1">partial: reports allocation only</span></td></tr><tr><td>OpenVMS index reclamation and bucket compaction (the full meaning of RECLAIM)</td><td><span class="ac-no">out of scope in this implementation</span></td></tr></tbody></table></div><div class="callout warn"><strong>CONV$RECLAIM is a compatibility placeholder.</strong> On OpenVMS,
<code>CONV$RECLAIM</code> reclaims free space in the index structure of a Prolog-3 indexed
file. In this implementation it reports file allocation statistics and does not perform index
reclamation. Treat it as a routine that links and returns success for compatibility, not as
working index-reclaim functionality.
</div><h6>Status and condition codes</h6><p>
VX/CONV$ returns the same <code>CONV$</code> condition-code vocabulary as OpenVMS. The codes
the conversion path actually produces are:
</p><div class="table-wrapper"><table><thead><tr><th>Symbol</th><th>Meaning</th></tr></thead><tbody><tr><td><code>SS$_NORMAL</code></td><td>Success.</td></tr><tr><td><code>CONV$_ORDER</code></td><td>Routines called out of order; the sequence resets to the files stage.</td></tr><tr><td><code>CONV$_NARG</code></td><td>No input file supplied.</td></tr><tr><td><code>CONV$_INP_FILES</code></td><td>Too many input files (more than 10).</td></tr><tr><td><code>CONV$_CONFQUAL</code></td><td>Conflicting qualifiers in the option vector.</td></tr><tr><td><code>CONV$_RTL</code></td><td>Record too long and truncate not requested.</td></tr><tr><td><code>CONV$_RTS</code></td><td>Record too short and pad not requested.</td></tr><tr><td><code>CONV$_OPENIN</code> / <code>CONV$_OPENOUT</code></td><td>Error opening the input or output file.</td></tr></tbody></table></div><p>
The broader OpenVMS <code>CONV$</code> catalogue defines many additional index, bucket, and
key error conditions. Those symbols exist for message compatibility but are not raised by this
implementation, because the indexed-file reclaim and load-index paths they describe are not
implemented here.
</p><h6>Deliberate divergences from OpenVMS CONVERT/FDL</h6><div class="table-wrapper"><table><thead><tr><th>Divergence</th><th>Reason</th></tr></thead><tbody><tr><td>One process-global state machine; conversions are not re-entrant.</td><td>Matches the single-context OpenVMS callable interface, so concurrent conversions in one process are a real constraint on Linux.</td></tr><tr><td>Output-file preparation is delegated to RMS and the indexed-file layer.</td><td>Linux has no native RMS on-disk format; VX/RMS and the indexed-file layer provide it.</td></tr><tr><td>Remote output uses SSH transport, with SSH failures mapped to RMS network status.</td><td>DECnet file access is replaced by an SSH-based transport on Linux.</td></tr><tr><td>Non-FDL conversions copy the input's organization verbatim.</td><td>Without an FDL there is no target attribute description, so attributes are copied rather than reformatted.</td></tr></tbody></table></div><h2 id="example">End-to-end example</h2><p>
The sequence below exercises the full state machine to convert a sequential account-export
file into an indexed file, using an FDL definition to describe the indexed output and padding
short records to the new record size. The filenames use the site's banking demo domain; the
routine names, argument order, option indices, and status symbols are the real API.
</p>
<pre><span class="cmt">/* VMS-style counted string descriptors */</span>
VMS_DESCR ifil = { <span class="str">"BANKING:ACCOUNTS.SEQ"</span> }; <span class="cmt">/* input: sequential export */</span>
VMS_DESCR ofil = { <span class="str">"BANKING:ACCOUNTS.IDX"</span> }; <span class="cmt">/* output: indexed file */</span>
VMS_DESCR fdl = { <span class="str">"BANKING:ACCOUNTS.FDL"</span> }; <span class="cmt">/* output layout description */</span>
U32 flags = 0, st;
<span class="cmt">/* 1. queue files: an output name resets the input list and saves output + FDL */</span>
st = <span class="kw">CONV$PASS_FILES</span>(&ifil, &ofil, &fdl, <span class="cmt">/*Exc*/</span> 0, &flags);
<span class="kw">if</span> (!ODD(st)) <span class="kw">return</span> st; <span class="cmt">/* CONV$_NARG / CONV$_INP_FILES / CONV$_ORDER */</span>
<span class="cmt">/* 2. options: plist[0] = word count, then the 19-slot vector.
set fdl (idx 16), pad (idx 8), and pad character (idx 9). */</span>
U32 opts[1 + 19] = {0};
opts[0] = 19; <span class="cmt">/* number of option words */</span>
opts[1 + 16] = 1; <span class="cmt">/* fdl */</span>
opts[1 + 8] = 1; <span class="cmt">/* pad */</span>
opts[1 + 9] = <span class="str">' '</span>; <span class="cmt">/* padchar */</span>
st = <span class="kw">CONV$PASS_OPTIONS</span>(opts, &flags);
<span class="kw">if</span> (!ODD(st)) <span class="kw">return</span> st; <span class="cmt">/* CONV$_CONFQUAL if pad and truncate both set */</span>
<span class="cmt">/* 3. convert; statblock[0] = number of statistics words requested */</span>
U32 stats[1 + 4] = { 4, 0, 0, 0, 0 };
st = <span class="kw">CONV$CONVERT</span>(stats, &flags);
<span class="cmt">/* stats[1]=files stats[2]=records stats[3]=exceptions stats[4]=valid */</span>
<span class="kw">return</span> st; <span class="cmt">/* SS$_NORMAL, or CONV$_RTL / CONV$_RTS */</span></pre>
<div class="callout"><strong>Call order matters.</strong> The same three calls in the same order run on OpenVMS
and on Linux without change. Calling them out of order returns <code>CONV$_ORDER</code> and
resets the sequence, so error handling that already exists on OpenVMS behaves identically.
</div><h2 id="quickref">Quick reference</h2><h6>Call order</h6><p><code>CONV$PASS_FILES</code> (once per input; the first call with an output name resets the
list) then <code>CONV$PASS_OPTIONS</code> then <code>CONV$CONVERT</code>. Any wrong order
returns <code>CONV$_ORDER</code> and resets to the files stage.
</p><h6>Limits and defaults</h6><div class="kw-grid"><div>max input files = 10</div><div>option slots = 19</div><div>statistics slots = 4</div><div>default create = 1</div><div>default fast_load = 1</div><div>default sort = 1</div><div>default work_files = 2</div></div><h6>Options consumed on the current path</h6><div class="kw-grid"><div>fdl</div><div>pad</div><div>padchar</div><div>truncate</div></div><h6>Statistics (CONVERT)</h6><div class="kw-grid"><div>files</div><div>records</div><div>exceptions</div><div>valid</div></div><h6>Status codes</h6><div class="kw-grid"><div>SS$_NORMAL</div><div>CONV$_ORDER</div><div>CONV$_NARG</div><div>CONV$_INP_FILES</div><div>CONV$_CONFQUAL</div><div>CONV$_RTL</div><div>CONV$_RTS</div><div>CONV$_OPENIN</div><div>CONV$_OPENOUT</div></div><h6>Related VX tools</h6><p>
VX/CONV$ works alongside the rest of the VX/RT toolset. The most closely related references
are:
</p><ul><li><a href="/technical/vx-rt-apis">VX/RT APIs</a> is the parent runtime that ships the CONV$ routines.</li><li><a href="/technical/vx-fdl-file-description-language-routines">VX/FDL - File Description Language Routines</a> and <a href="/technical/api-fdl-file-definition-language">FDL$ - File Definition Language</a> build the output file from an FDL definition.</li><li><a href="/technical/vx-rms-sys-routines-for-rms">VX/RMS - SYS$ Routines for RMS</a> and <a href="/technical/api-sys-interface-routines">SYS$ - SYS$ Interface Routines</a> read and write every record.</li><li><a href="/technical/api-str-string-interface-routines">STR$ - STRING Interface Routines</a> and <a href="/technical/api-lib-general-routines">LIB$ - General Routines</a> marshal filename descriptors and check for file existence.</li><li><a href="/technical/api-sor-interface-to-sort">SOR$ - Interface to SORT</a> and <a href="/technical/vx-sort-vms-sor-merge">VX/SOR - OpenVMS SORT MERGE</a> share the sort, merge, and work-file option encoding.</li><li><a href="/technical/api-ots-data-conversion-routines">OTS$ - Data Conversion Routines</a> is the sibling numeric and type conversion API, and <a href="/technical/vx-datax-vms-rms-data-exchange">VX/DATAX - OpenVMS RMS Data exchange</a> is an adjacent RMS data-exchange tool.</li></ul></div>