Any file on a conventionally designed UNIX filesystem whose reference count (e.g. the sum of the hardlink count and the number of open file handles*) reaches 0 is removed. However, on modern UNIX systems, the
rmdir system call removes an empty directory in a single operation rather than removing
In historical UNIX systems, however, this system call did not exist. Instead, the
rmdir command was a setuid program (source code can be found here) which checked that a directory was empty (other than the special entries), and then removed
., in that order, and then removed the directory itself, all with the
unlink system call which only root was permitted to use on directories (hence why the command was setuid). So, on those systems, the link count of a directory would momentarily be 1 after
. was removed but before the directory was removed from the parent directory, then it would be 0.
rm command, incidentally, prevented even root from removing directories. And
rm -r would call out to the
rmdir command to remove directories after emptying their contents.
On these historical systems, misusing the
unlink call from a program running as root, running into a race condition with
mv, or creating a file in a process whose current directory has been deleted (modern systems prevent this), could result in dangling files or directories which have a hardlink count above 0 but do not exist in the directory tree. This condition was detected by
dcheck, and is still one of the checks in
fsck since it remains physically possible on most filesystems.
Filesystems are, incidentally, not required to implement directories (including
..) as normal files that have hardlinks. On these filesystems, the hardlink count of a directory will always be reported as
0 (but of course, its existence within the parent directory qualifies for a "reference count" of 1).
The behavior of of a removed directory (e.g. when examined by a process which has it already open or has it as its current directory) and the exact meaning of the "link count" of a directory are unspecified. On Mac OS X, for example, it will report a hardlink count of 2, even though it has no real hardlinks. Even though
.. do not appear in the listing, the directory can be opened and
stat may be called with the name
... On Linux, the link count is 0 but
.. likewise still work.
Mac OS X also reports the number of all files in a directory as the link count, instead of just the number of subdirectories. But it is 2 even when
.. are gone.
*This includes normal open descriptors, memory-mapped sections (including e.g. executing binaries and shared libraries), and process current directories.