Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 9 Dec 1997 04:22:28 +1100
From:      Bruce Evans <bde@zeta.org.au>
To:        freebsd-bugs@FreeBSD.ORG, njs3@doc.ic.ac.uk
Subject:   Re: confusing rm/rmdir error messages
Message-ID:  <199712081722.EAA27406@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>Is this considered normal:

Surprising behaviour in this area is normal, but not for FreeBSD.

>[root@sprite56 /usr]# ln -s /sunsite/packages/FreeBSD/packages-current/ packages
>[root@sprite56 /usr]# ls -lad packages/
>drwxr-xr-x  45 root  wheel  8192 Dec  8 13:05 packages/
>[root@sprite56 /usr]# ls -lad packages 
>lrwxrwxrwx  1 root  wheel  43 Dec  8 14:19 packages -> /sunsite/packages/FreeBSD/packages-current/
>[root@sprite56 /usr]# rm packages/
>rm: packages/: is a directory			/* its a directory! */

This is correct.  Normal surprising behaviour is exhibited by gnu rm
(fileutils-3.13 version) under Linux-2.0.32.  rm(1) strips the slash
and then removes "packages".  Syscalls exhibit conflicting behaviour:

	rmdir("packages/");		Not a directory   [symlink not followed]
	unlink("packages/")		Operation not permitted  [followed]
	fd = open("packages/", ...):	succeeds                 [followed]
	read(fd, buf, 1):		Is a directory

The syscalls work right under FreeBSD.  The symlink is followed
consistently (and you can read ffs directories :-).

>[root@sprite56 /usr]# rmdir packages/
>rmdir: packages: Not a directory		/* its not a directory! */

Bug in rmdir(1).

>It seems like rmdir is stripping off any trailing '/' from the pathname.
>I don't think it should do that.

Yes.  This bug was introduced just last December, or I would have fixed
it when I fixed trailing slash semantics in the kernel.  This also fixes
bugs in trailing slash stripping in the non-`-p' case:
- "/" was stripped down to "" and then "" was used
- there was undefined behaviour for path "" (--p is wrong if p points to
  the beginning of an array).

The -p case seems to be handled correctly.  POSIX specifies `rmdir -p foo'
recursively having the same effect as:

	rmdir foo
	rmdir -p `dirname foo`

and assuming that our implementation of dirname(1) is correct, dirname
strips trailing slashes, and this is good since we probably don't want to
remove directories that happen to be pointed to by intermediate symlinks.
OTOH, leaving the trailing slash for plain rmdir is useful since you can
just not use a trailing slash if you don't want any symlink followed.
Bugs in the trailing slash stripping don't occur because the "/" and ""
cases get weeded out before the buggy code is reached.

Bruce

diff -c2 rmdir.c~ rmdir.c
*** rmdir.c~	Sat Mar 29 14:09:13 1997
--- rmdir.c	Tue Dec  9 03:42:26 1997
***************
*** 79,90 ****
  
  	for (errors = 0; *argv; argv++) {
- 		char *p;
- 
- 		/* Delete trailing slashes, per POSIX. */
- 		p = *argv + strlen(*argv);
- 		while (--p > *argv && *p == '/')
- 			;
- 		*++p = '\0';
- 
  		if (rmdir(*argv) < 0) {
  			warn("%s", *argv);
--- 79,82 ----



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199712081722.EAA27406>