Subject: bin/9643: Unexpected behavior from rm -rf
To: None <gnats-bugs@gnats.netbsd.org>
From: William O Ferry <woferry@warp.wofme.com>
List: netbsd-bugs
Date: 03/20/2000 02:09:44
>Number:         9643
>Category:       bin
>Synopsis:       Unexpected behavior from rm -rf
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Mar 20 02:09:01 2000
>Last-Modified:
>Originator:     William O Ferry
>Organization:
>Release:        <NetBSD-current source date> sup'ed 2000/03/16
>Environment:
	
System: NetBSD slipstream 1.4U NetBSD 1.4U (kernel) #22: Fri Mar 17 00:03:32 PST 2000 root@slipstream.wofme.com:/usr/obj.i386/kernel i386


>Description:
	
	Attempting to remove a nonexistant file from a read-only directory
with "rm -rf" causes the "Read-only file system" error to be displayed, rather
than no error at all.  "man rm" says that with the -f flag "If the file does
not exist, do not display a diagnostic message or modify the exist status to
reflect an error.", yet rm returns an error if the file does not exist but is
in a read-only filesystem.
>How-To-Repeat:
	
Mount a filesystem as read-only.
Attempt to "rm -rf" a non-existant file in that mountpoint.

Ran across this one doing a "make clean" in an already cleaned, read-only
(using obj dirs) /usr/src.
>Fix:
	
	Not sure exactly which piece of code should be corrected here.  In rm
the "problem" begins with line 194.  If the -r and -f flags were set we end
up at this clause, and needstat is false.  So we fall out of the switch
statement and enter the second one, which ends up in the default case.
unlink() sets errno to EROFS, which does not count as true for the
NONEXISTENT() macro, so we end up at the warn() and print the error message
for EROFS.  I suspect this code path could be adjusted to prevent this from
happening, I'm not sure where the best place to modify things would be.

	The other possible problem is that unlink() returns EROFS in this
case.  Should unlink() return ENOENT if the file doesn't exist whether the
directory is writable or not, or is EROFS the right error response?
>Audit-Trail:
>Unformatted: