From dhesi@cirrus.com Tue Jan 14 21:34:48 1992 From: dhesi@cirrus.com (Rahul Dhesi) Newsgroups: comp.unix.misc Subject: Re: rmdir("foo/") returns EINVAL - why? Keywords: rmdir SunOS BSD Date: 14 Jan 92 21:44:20 GMT Organization: Cirrus Logic Inc. In <1992Jan13.151341.2303@dcs.glasgow.ac.uk> sinclair@dcs.glasgow.ac.uk (Duncan Sinclair) writes: >In SunOs 4.1, when I append a '/' or even a "/." to the end of a >directory used as an argument to rmdir(2), I get EINVAL. ("The directory >referred to by path is the current directory, `.'.") Two facts to keep in mind: 1. In a UNIX filesystem, the root directory has a slash in its name. 2. When the infamous kernel routine "namei" encounters a null filename component in a pathname, it inteprets it as referring to the current directory. The combination of 1 and 2 above makes more sense than 2 alone. It would be nice if in every case the sequence directory_name slash filename would yield a syntactically valid pathname. But if the directory_name happens to be the root directory, you end up with a pathname that looks like: //name So it makes sense for the kernel to squeeze out multiple consecutive slashes. Generalizing this, it makes sense for the kernel to treat a null filename component as if it were ".". So "//name" is treated like /./name, which makes sense. Extending the reasoning, "name/" should be treated as "name/.". Examples of how useful this is. 1. In a makefile: ROOTDIR = / BINDIR = usr/bin install: myprg mv myprg $(DESTDIR)/$(BINDIR)/myprg The final destination expands to //usr/bin which still makes sense. 2. Interactively, when you move a file to another directory, if you mistype the name of the destination directory, you can end up simply renaming the file. To avoid any problems, specify the destination directory name with a trailing slash. % mv xyzzy newdir # is newdir a directory or a filename? % mv xyzzy newdir/ # "newdir/" means "newdir/." -- must be dir Not all UNIX derivatives get this right. But the only correct way to interpret a trailing slash is as if it were "/.". I believe that SunOS 4.x, 4.3BSD, and 4.3BSD-tahoe get it right, while SVR2 and possibly SVR3 get it wrong. Also try: % cd "" If your kernel is interpreting null filename components correctly, and your shell leaves the directory name alone, the above cd will leave you where you are, i.e., in ".". Any other behavior is wrong. However, you may find that /bin/sh complains about a bad directory (as it does on my SunOS 4.1.1 machine). This is an example of "wrong" but desirable behavior, as it protects you against shell scripts like this one: #! /bin/sh NEEDEDDIR=/some/path/name cd "$NEEDEDIR"; find . -mtime +1 -exec rm -f {} \; Due to the misspelling, the last line in the script is really cd ""; find . -mtime +1 -exec rm -f {} \; which could be disastrous, so you can't blame the shell for protecting you. The *kernel*, however, should always interpret a null filename component as referring to the current directory. -- Rahul Dhesi UUCP: oliveb!cirrusl!dhesi "You're even nuttier than we've come to expect of you." -- Doug Gwyn