Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Overview

The cms-spool crate implements the VM/CMS virtual spool subsystem. It models the unit-record device queues – reader, punch, and printer – that CMS virtual machines use to exchange files and produce printed output.

Spool Concepts

Devices

Three virtual unit-record devices are supported, mirroring the IBM VM/CMS model:

DeviceAliasesPurpose
ReaderRDR, RIncoming files from other users
PrinterPRT, PROutput destined for printing
PunchPUN, PCH, PUCard-punch output

Classes

Each device has an associated spool class (a single uppercase letter, A-Z). Classes control routing and filtering – for example, QUERY READER CLASS N lists only class-N reader files.

Spool IDs

Every file placed in a spool queue is assigned a unique numeric spool ID. The ID is used by PURGE to target individual files for removal.

Commands

All commands use CMS-style abbreviation matching (minimum unique prefix).

CommandMin AbbrevExampleDescription
SPOOLSPSP PRT CLASS A DEST OPERATORConfigure a device’s class, destination, hold, continuous, or copy count
SENDFILESESE MYFILE DATA A TO JONESSend a file to another user’s reader
RECEIVERECREC NEWNAME DATA ADequeue the next file from your reader
QUERYQQ READERList files waiting in a device queue
PURGEPURPUR READER 12345 / PUR RDR ALLRemove one or all files from a queue

These are represented in code by the SpoolCommand enum in command.rs, which is parsed from raw token vectors via SpoolCommand::parse().

SpoolManager and the Backend Trait

SpoolManager<B> is the main entry point for spool operations. It is generic over the SpoolBackend trait, which abstracts the storage layer:

pub trait SpoolBackend {
    fn enqueue(...) -> Result<u64>;
    fn dequeue(device) -> Result<(SpoolFile, String)>;
    fn list_queue(device, class) -> Result<Vec<SpoolFile>>;
    ...
}

Two backend implementations are provided:

  • InMemoryBackend – hash-map-based storage used in tests.
  • DirectoryBackend – filesystem-backed storage using per-device subdirectories (rdr/, prt/, pun/) with .meta sidecar files.

SpoolManager owns per-device DeviceConfig structs that track the current class, destination, hold, and copy-count settings. The SPOOL command modifies these configs; SENDFILE and RECEIVE use them when enqueuing or dequeuing files.

SpoolCommandResult carries a return code and message list back to the caller, following CMS conventions (rc 0 = success).

Integration with CMS

The spool subsystem plugs into cms-core’s CommandProcessor through the ExtCommandHandler trait. When the command processor encounters an unrecognized command, it delegates to registered external handlers. The spool handler matches SPOOL, SENDFILE, RECEIVE, QUERY, and PURGE, parses them into SpoolCommand variants, and executes them against the SpoolManager. This keeps the spool logic decoupled from the core CMS command loop while still appearing as first-class CMS commands to the user.