How MS-DOS 6.22 Parses Input Redirection
In MS-DOS 6.22, standard input redirection using the less-than symbol
(<) is handled entirely by the default command
processor, COMMAND.COM, prior to the execution of any
target program. When a command line containing < is
submitted, the shell parses the string, isolates the redirection
operator, strips the redirection parameters from the argument list, and
reassigns standard input (File Handle 0) to point directly to the
specified file. This ensures that the downstream utility receives clean
arguments and reads from the designated file rather than the keyboard
buffer without needing any native redirection awareness.
1. Command Line Scanning and Parsing
When a user submits a command, COMMAND.COM reads the
entire text string into its internal command buffer. Before identifying
program arguments or invoking the executable, the parser scans the input
line sequentially from left to right for redirection delimiters,
specifically <, >, and
|.
When the parser encounters the < symbol, it executes
the following steps:
- Whitespace Truncation: It ignores any whitespace
immediately following the
<token. - Filename Extraction: It reads subsequent non-whitespace characters until it encounters another delimiter (such as a space, another redirection symbol, or an end-of-line carriage return). This token is identified as the source file path.
- Command Tail Reconstruction: The shell modifies the
original command buffer in memory. It splices out the
<operator and its associated filename, concatenating the preceding command segment with any trailing arguments. The sanitized string forms the final command tail placed at offset0x80in the child process's Program Segment Prefix (PSP).
2. Handle Management via MS-DOS Interrupts
MS-DOS tracks input/output through a table of 16-bit handles. Handle
0 is universally reserved for STDIN (Standard
Input), which by default maps to the CON (console) device.
To reassign Handle 0 to the target file,
COMMAND.COM utilizes MS-DOS API functions via software
interrupt INT 21h:
- Saving the Console Handle:
COMMAND.COMcallsINT 21h, AH=45h(Duplicate File Handle) on Handle0. This returns an auxiliary handle referencing the original console input, preserving the state so the shell can restore the console after the child process terminates. - Opening the Target File: The shell calls
INT 21h, AH=3Dh(Open Existing File) with the extracted filename, settingAL=0for read-only access. If the file does not exist,COMMAND.COMhalts processing, displays the error messageFile not found, and does not execute the target program. - Forcing Handle Duplication: Upon successfully
opening the file, the shell receives a temporary file handle. It then
calls
INT 21h, AH=46h(Force Duplicate File Handle), passing the new temporary handle inBXand0inCX. This atomic operation closes Handle0's link toCONand points Handle0directly to the open file entry. - Closing the Temporary Handle:
COMMAND.COMissuesINT 21h, AH=3Eh(Close File) on the original temporary handle returned byAH=3Dh. Because Handle0now duplicates that open file structure, the file remains open exclusively on Handle0.
3. Execution and Inheritance
With the Job File Table (JFT) updated, COMMAND.COM
invokes INT 21h, AH=4Bh (EXEC) to load and execute the
binary.
Because child processes inherit the parent's file table entries by
default, the child executable starts with Handle 0 pointing
directly to the file on disk. Whether the program reads input using
high-level DOS services (like INT 21h, AH=3Fh Read from
File/Device or INT 21h, AH=0Ah Buffered Input), standard C
library calls like scanf() or getchar(), or
BIOS interrupts that fall back to standard handles, all reads
sequentially consume the redirected file's contents until an End-Of-File
marker (EOF, byte 0x1A or physical file
length) is encountered.
4. Teardown and Handle Restoration
Once the child program completes its execution and exits via
INT 21h, AH=4Ch, control returns to
COMMAND.COM.
The shell invokes INT 21h, AH=46h once more, passing the
auxiliary handle saved earlier to restore Handle 0 back to
the console (CON). Finally, COMMAND.COM calls
INT 21h, AH=3Eh to close the auxiliary handle, fully
resetting the command processor's environment for the next prompt.