Every file in the UNIX filesystem - and a directory is just a file, albeit a rather special one - is represented by one inode (1.22) and one or more names (directory entries (18.2)). In a sense the inode is the file; each name is a link (18.4) to this inode. An ordinary file may have anywhere from one to several thousand links (the exact limit is system dependent), but a directory never has any fewer than two. Every directory has at least two names.
Suppose you start in /usr/tmp and do a mkdir x. What are the two links to x? They are /usr/tmp/x and /usr/tmp/x/., directory entries in /usr/tmp and /usr/tmp/x, respectively. This might seem rather odd at first: how can a directory name itself? It's not hard: first you create /usr/tmp/x, a completely empty directory, then link /usr/tmp/x to /usr/tmp/x/. and you're halfway done. All link does is take its first name and turn it into an inode - the file itself - then make a new entry for the second name, pointing to that inode. You must also link /usr/tmp to /usr/tmp/x/.. to make a properly formed directory. The mkdir program and system call both do all this properly; and there is no other way for anyone except the superuser (1.24) to create a directory.
Here is where the trouble creeps in. All unlink(2) does is take
the name it is given, convert it to an inode, and remove the name.
If the name was the last link to that inode, the file itself is
destroyed as well; if not, it is left intact and may still be
accessed by its other name(s). So what happens if you unlink a
directory? Well, if it is completely empty, it goes away and
everything is fine. However, if it still has .
and
..
in it - and it almost certainly will - things are
not so good. The .
link to the directory itself still
exists, so the file that is the directory is not deleted. The
name /usr/tmp/x is deleted, and that leaves us with a pretty
problem: how can we get rid of that last .
and ..
?
The answer is that we cannot. That directory will stick around forever. Worse, it has in it another name for, or link to, /usr/tmp, which means that that, too, cannot be deleted. Of course, fsck (which does not use the regular filesystem mechanisms) can clean this up, but this usually requires a system shutdown. [fsck is a filesystem-checking program that the system administrator runs. -JP ] For this reason, again, only the superuser may unlink a directory. Ordinary processes must use the rmdir program or system call.
Incidentally, the mkdir(2) and rmdir(2) system calls do not exist on older UNIX systems. On these systems, you must use careful fork-exec (38.2) sequences to run the mkdir and rmdir programs.
- in net.unix on Usenet, 25 July 1986