How MS-DOS 6.22 Handles SET Environment Variables

In MS-DOS 6.22, the SET command is an internal function of the command processor (COMMAND.COM) used to create, modify, and delete environment variables stored in a dedicated memory block. When a user or batch script executes SET, the operating system parses the input, converts variable names to uppercase, and updates a contiguous, null-delimited segment of memory allocated for environment data. If the block lacks sufficient space, DOS returns an "Out of environment space" error, making the size and location of the environment block critical to system operation.

Command Parsing and Formatting

When COMMAND.COM encounters the SET command, it processes the text following the command keyword:

  • Displaying Variables: If SET is executed without parameters, COMMAND.COM reads the entire environment segment from the first byte to the double-null termination and prints each entry to standard output.
  • Key and Value Separation: If parameters are provided, the parser searches for the first equal sign (=). The text to the left becomes the variable name, and the text to the right becomes the value.
  • Case Normalization: MS-DOS converts the variable name to uppercase characters before storing it. The value assigned to the variable preserves its original casing, spaces, and special characters.
  • Deletion: If a variable name is followed by an equal sign with no trailing value (e.g., SET VAR=), COMMAND.COM treats this as a removal instruction.

Memory Layout of the Environment Block

MS-DOS stores environment variables in a dedicated memory segment managed via Memory Control Blocks (MCBs). The structure follows a strict format:

  1. Format of Entries: Each variable is stored as an ASCII string formatted as NAME=VALUE, terminated by a single null byte (00h).
  2. End-of-Block Marker: The final variable in the list is terminated by an additional null byte (00h), creating a double-null sequence that signals the end of the environment data.
  3. Program Path Information: In MS-DOS 6.22, a word count followed by the fully qualified path of the currently executing program is placed directly after the terminating double null.

Adding, Modifying, and Deleting Entries

When modifying the environment, COMMAND.COM scans the memory block sequentially from the beginning:

  • To Modify an Existing Variable: If the variable name already exists, MS-DOS removes the old entry. If the new value requires the same or fewer bytes, it updates the space in place. If the new entry is larger, DOS shifts subsequent data downward in memory to accommodate the larger string, provided the overall environment limit is not exceeded.
  • To Delete an Existing Variable: DOS locates the NAME=VALUE string, deletes it, and shifts all remaining entries up toward the beginning of the block to eliminate the gap. The end-of-block null markers are adjusted accordingly.
  • To Add a New Variable: DOS searches for the double-null sequence marking the end of the data. If the remaining allocated memory accommodates the new string, the string is appended, followed by the terminating null bytes.

Memory Size Limits and the PSP

By default, MS-DOS 6.22 allocates an environment block of 256 bytes for the primary shell. If a SET command requires more bytes than remain in the allocated block, the operation fails, and DOS outputs the error: Out of environment space.

System administrators increase this allocation by modifying CONFIG.SYS using the SHELL command:

SHELL=C:\DOS\COMMAND.COM C:\DOS\ /E:1024 /P

The /E:size switch defines the master environment block size in bytes (ranging from 160 to 32,768 bytes).

Environment Inheritance

Each process launched under MS-DOS receives its own copy of the environment. The Program Segment Prefix (PSP) of an executing program contains a pointer at offset 2Ch that holds the segment address of its environment block.

When a program or secondary shell launches, DOS creates a snapshot of the parent environment, truncating any unused memory to fit the active variables. Consequently, changes made with the SET command inside a child shell or batch process launched in a subshell only alter the child's local environment block and do not persist in the parent COMMAND.COM environment after the child process exits.