Sometimes the quest for backwards compatibility has unintended consequences. In some cases, the presumably beneficial backwards compatibility turns into a source of problems. The costs end up far outweighing the benefits, yet the “feature” may be difficult to get rid of. If only it hadn’t been implemented in the first place…
If you’re on a Windows system, try a small experiment. Take an existing text file, say
foo.txt, and try renaming it to
aux.txt. Oops, it doesn’t work:
Try renaming to
aux.with.extension. It doesn’t work either. That surely looks like a bug, doesn’t it? Why would the operating system arbitrarily refuse to rename a perfectly good file? In fact Windows does that to be backwards compatible with an operating system that was obsolete before many current PC users were even born.
Reserved names in DOS 1.0
In DOS 1.0, character devices existed in the same namespace as ordinary files. It is questionable whether that was a good idea even in 1981, but it was done for compatibility with CP/M. What it meant was that DOS reserved several “special” names for built-in devices. Part of the problem was that there was in fact nothing special about the names themselves, it was just a somewhat arbitrary list which included (looking at IBMDOS.COM shipped with PC DOS 1.0):
LPT1 (parallel port),
AUX (auxiliary device),
COM1 (serial port),
CON (console), and
NUL (the null device). Additional names like
LPT7 were also reserved (for numbers in the 1-9 range).
In DOS 1.x, there were no installable device drivers yet, so the list was predictable. When DOS 2.0 introduced installable drivers, the scheme applied to all devices, not just the ones built into DOS. By convention, installable character drivers included a dollar sign in the device name, such as
POWER$. In some cases, the name was merely chosen to be “unusual”, such as
XMSXXXX0 (for HIMEM.SYS). This was done to reduce the probability of clashes with actual file names.
However, the real bug-formerly-feature was elsewhere. In DOS 1.x, like CP/M before it, there were no directories. Files were not organized in a hierarchy, they simply existed in a flat name space on a (floppy) disk. In the era of 160K or 320K floppies, there were only so many files that would fit on a disk, therefore the lack of hierarchy didn’t pose major difficulties.
Reserved names in DOS 2.0
When DOS 2.0 introduced support for fixed disks (typically 5-10MB in size), a flat namespace was no longer an option. Microsoft chose to implement a UNIX-style hierarchical directory structure (along with numerous other UNIX-like features). And this is where backwards compatibility comes in.
Applications written for DOS 1.x knew nothing of directories. Yet it was desirable to run them under DOS 2.0, and it was desirable to run them from subdirectories. When run in a subdirectory, a DOS 1.x application would think that the directory is the entire disk. There was just a small problem with the built-in devices. Since DOS 1.x applications expected the
PRN, etc. devices to exist alongside regular files, a decision was made to replicate the special names throughout the entire directory hierarchy. Because of that decision, probably made sometime in 1982, you are now unable to create a file called
aux.txt on a 64-bit Windows system 30 years later.
This was markedly different from UNIX where devices were typically accessed through the
/dev directory. But in UNIX, even though it’s much older than DOS, hierarchical directories were designed in rather than merely bolted on later.
Back in 1982-83, Microsoft and IBM could have decided to create a similar special device directory, or they could have decided to only propagate device names throughout the directory hierarchy for legacy DOS 1.x applications. But they did neither. The problem was compounded by the fact that for device names, DOS does did consider extensions at all. That’s why any file name whose base portion is e.g.
PRN is reserved.
As a result, applications (and batch files, in many cases) continued to refer to
PRN and expected them to exist “everywhere”. As time went on, the amount of software referring to those special files only grew and getting rid of them was harder and harder.
Reserved names in Windows NT
When Windows NT was designed, use of these special names was so widespread that it had to be replicated in the new operating system. In NT the DOS-compatible names aren’t hardcoded, but they do exist by default. Interestingly, in the name of consistency and backwards compatibility, these device names are propagated even on network shares hosted by foreign operating systems.
That provides for amusing (or annoying) situations where e.g. a Samba share on a Linux or OS X system contains a file named, say,
com5.txt. Windows will see this file in directory searches, but will be unable to open it. It is very difficult to argue that this is a useful feature.
The situation in Windows NT is a little more complicated. The core OS does not subscribe to the notion of reserved filenames. The backwards compatibility is implemented in the Win32 layer, which is admittedly 99.99% of what comprises Windows NT today. However, it does mean that for example POSIX applications can create and access files with “reserved” names unimpeded. Microsoft in fact recommends the POSIX rm utility for getting rid of undesirable files with reserved filenames which cannot be easily removed through the Windows user interface.
Clearly this feature has outlived its usefulness, but removing it would no doubt lead to subtle and not so subtle breakage in unexpected places. For example, batch files which redirect output of programs to
NUL (in order to throw it away) would suddenly start creating files called
NUL all over the place. And that’s probably one of the more benign examples.
The moral of the story is simple: When considering backwards compatibility, consider the future first; it’s often much longer than the past! And in general, try not to end up in an inconvenient situation where the best explanation is “it seemed like a good idea at the time”.