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:

  1. Whitespace Truncation: It ignores any whitespace immediately following the < token.
  2. 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.
  3. 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 offset 0x80 in 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.COM calls INT 21h, AH=45h (Duplicate File Handle) on Handle 0. 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, setting AL=0 for read-only access. If the file does not exist, COMMAND.COM halts processing, displays the error message File 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 in BX and 0 in CX. This atomic operation closes Handle 0's link to CON and points Handle 0 directly to the open file entry.
  • Closing the Temporary Handle: COMMAND.COM issues INT 21h, AH=3Eh (Close File) on the original temporary handle returned by AH=3Dh. Because Handle 0 now duplicates that open file structure, the file remains open exclusively on Handle 0.

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.