17

The environment variables %TMP% and %TEMP% are the same. Reading the interesting Raymond Chen blog https://devblogs.microsoft.com/oldnewthing/20150417-00/?p=44213, it seems that %TEMP% was introduced in MS-DOS 2.0.

MS-DOS 2.0 introduced the ability to pipe the output of one program as the input of another. Since MS-DOS was a single-tasking operating system, this was simulated by redirecting the first program’s output to a temporary file and running it to completion, then running the second program with its input redirected from that temporary file. Now all of a sudden, MS-DOS needed a location to create temporary files! For whatever reason, the authors of MS-DOS chose to use the TEMP variable to control where these temporary files were created.

What version of MS-DOS or Windows introduced %TMP%? Going by the blog, it may be the same version as that which introduced Get­Temp­File­Name.

The result of all this is that the directory used for temporary files by any particular program is at the discretion of that program, Windows programs are likely to use the Get­Temp­File­Name function to create their temporary files, in which case they will prefer to use TMP.

The first version of MS-DOS to introduce environment variables was 2.0. Microsoft released the original sources of MS-DOS 1.25 and 2.0 https://github.com/microsoft/MS-DOS. I searched for “TEMP” and found “CreateTempFile” but not %TEMP% nor any other environment variables. What were the environment variables shipped with MS-DOS 2.0? Are they not in the linked source code?

1
  • 9
    Sadly, they're not the same as in aliases. If you change one you need to change the other to match if you for sure want all your temp files in the same place. (First, some programs, I guess, might still look for TEMP or TMP explicitly, and second the API GetTempPath has a search order which is easy to forget (or not know) so that if you set, e.g., TEMP and it is different from a non-empty TMP you'll be puzzled...)
    – davidbak
    Commented Sep 4, 2022 at 20:56

1 Answer 1

20

MS-DOS 2.0 does not use any special environment variable to locate a temp-directory nor does it use such at all. Temporary files for piping will be created in the root directory (*1) of the current drive (*2) and named

%PIPEx.$$$

with x being 1 or 2 used consecutive, as shown in the now public code for DOS 2.0.

The file name templates can be found in the source file RDATA.ASM at line 173 and 174. They are used within TCODE.ASM. TCODE contains, as the name tells (TransientCODE), the transient parts of COMMAND.COM, i.e. the parts that may be purged during a filter (program) run and reloaded after.

These names were the only temporary files MS-DOS - or more exact COMMAND.COM used. After all, it wasn't a function of DOS, but of the shell that executed all programs in sequence and redirected in-/output accordingly.


Environment Variable Usage

it seems that %TEMP% was introduced in MS-DOS 2.0.

Not really, Mr. Chen might need to check again. As mentioned, MS-DOS 2 - and AFAIK at least until 3.3 - did not use a temp-directory or either of the variables (*3).

The attribution might come due the behaviour of MS-DOS 5.0 and later setting TEMP in the AUTOEXEC.BAT created by the installer — pointing not at a temporary directory, but at the DOS installation directory, as Stephen Kitt checked.

What version of MS-DOS or Windows introduced %TMP%?

TMP was used by the Microsoft C compiler, as early as 3.0 (*4). Windows 3.0 might have been the first OS to use TEMP - at least does the Microsoft Windows User's Guide mention setting this variable p.538. It can be speculated that the different name was used to avoid any conflict with language tools using TMP (*5).

Get­Temp­File­Name function to create their temporary files, in which case they will prefer to use TMP

Not really, as GetTempFileName only cares about creating the file name, not looking up any drive, path or directory from any environment setting.


Temp-File Functions

It wasn't until DOS 3.0 that a function to create temporary name was introduced. Int 21h Function 5Ah CreateTempFile created a file in a given directory (path must be provided by the caller) using date and time as file name (*6).

Get­Temp­File­Name on the other hand is a Windows function that works much like the DOS function, but will not open that file. The name will be composed of a user supplied 3 character prefix and a 4 character unique number (16 bit as HEX) as <path>\<pre><uuuu>.TMP. If the unique number is supplied by the windows runtime it will be guaranteed to not exist.

Another Windows function would be GetTempDrive which returns the drive used for temporary files as a single character (*7).

Both functions are present since Windows 2.03. Together they provided a way for Windows programs to create temporary files in the root directory of a given drive - much the same way DOS did for pipes.

It wasn't until WIN32 that GetTempDrive got superseded with GetTempPath, which now implements the search sequence Mr. Chen talks about:

  • The path specified by the TMP environment variable.
  • The path specified by the TEMP environment variable.
  • The path specified by the USERPROFILE environment variable.
  • The Windows directory.

MS offers some documentation how to Create and Use a Temporary File. Except, it's outdated already, as GetTempPath got with Win10, a little brother GetTempPath2, which is to be used instead. It will consider as well privileges to pick the final location.


*1 - Somehow I remembered it to be the current directory on that drive as well, but looking at the code shows it's always in the root directory.

*2 - I bet every creator of a non trivial filter did at least once run into the bug screwing a pipe by changing the default drive, but not changing it back before exiting :))

*3 - The only environment variables used by DOS or COMMAND.COM with MS-DOS 2.0 are

  • COMSPEC
  • PATH
  • PROMPT

And only the first two of them are set by default by COMMAND.COM under DOS 2.x/3.x. PROMPT will be observed, but needs to be added by user commands. In fact, DOS 2.0 even added a build in PROMPT command, a thin veil for SET PROMPT=.

*4 - I'm not sure if the Lattice C based Versions before 3.0 did already use TMP as well.

*5 - I could imagine screwing an installation when compiling and testing on the same machine with compilers and Windows assuming the temp dir being theirs :)

*6 - Which had it's own pitfall as that file wasn't cleaned up by DOS after a program exited - or been aborted - leading to the first case of dead-file-hording under DOS/Windows :)

*7 - In reality it returns not just a char (in AL) but a 16 bit int - or better two char - in AX with AH always containing a colon (:), so calling functions could store both with a single machine instruction at the start of the path they are building. Yeah, early DOS and Windows was really build with code path saving in mind.

9
  • Good find. RDATA.ASM is resident data, which is presumably in memory data? TCODE.ASM lines 243 and 244 are PUSH CS and POP DS. MOV DS CS would have been faster, or maybe that register combination is not possible? Commented Sep 4, 2022 at 20:43
  • 2
    It is annoying that nowadays, TEMP is in the roaming profile. This means you have to go into every roaming profile to clear out temp - can't just clear %TEMP% and assume all the temp files have been wiped.
    – cup
    Commented Sep 4, 2022 at 20:46
  • @SingleMalt No, the 8086 can not move between segment registers. This is due them being part of the BIU, not the EU. Going thru stack (or AX) is the usual way.
    – Raffzahn
    Commented Sep 4, 2022 at 21:04
  • 1
    @cup: did you mean every roaming profile of a specific user on multiple computers? Or every roaming profile on a specific computer for all users on that computer? Because a user should definitely not be allowed to do the latter, those files (temporary or not) do not belong to them.
    – paxdiablo
    Commented Sep 4, 2022 at 23:17
  • 2
    I haven’t checked MS-DOS 4.01, but MS-DOS 5.0 sets TEMP in the AUTOEXEC.BAT created by the installer — pointing not at a temporary directory, but at the DOS installation directory. MS-DOS 6.*x* does the same. Commented Sep 5, 2022 at 9:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .