svn commit: r272372 - stable/10/bin/rm

Bruce Evans brde at optusnet.com.au
Sat Oct 4 05:50:06 UTC 2014


On Fri, 3 Oct 2014, Garrett Cooper wrote:

> On Oct 2, 2014, at 16:34, Bruce Evans <brde at optusnet.com.au> wrote:
>
>> There is still the larger problem with fts_read().  Applications like rm
>> are specified to do a complete tree walk, with special handling for files
>> that do not exist.  If fts_read() is going to abort in the middle of a
>> tree walk, then it is unusable for implementing applications like rm.
>
> +1. In this case I was doing a du -sh /* while I was running rm -Rf /rel (an old make release directory tree). This stopped the du -sh:
>
> $ sudo du -sh /*
> 8.0K    /COPYRIGHT
> 996K    /bin
> ...
> du: /rel/usr/ports/net/fsplib: No such file or directory
> du: fts_read: No such file or directory

It is fine garbage collection to delete itself, but that should be more
like "du: du: No such file or directory" :-).

> 	The problem with changing fts_read to ignore ENOENT or other errors will break compatibility with Linux [and other OSes potentially], and is not the correct solution for this issue. I do however think that the errnos to ignore with -f should be...
>
> - EACCES
> - ENOENT
> - EPERM

No, the only error that can be safely ignored in most cases is ENOENT.
EACCES and EPERM mean that rm has failed to remove the requested files.

More errors could be ignored under a different option.

> 	… as filtering out these errors would handle the case that -f should handle according to the manpage:
>
>     -f      Attempt to remove the files without prompting for confirmation,
>             regardless of the file's permissions.  If the file does not
>             exist, do not display a diagnostic message or modify the exit
>             status to reflect an error.  The -f option overrides any previous
>             -i options.

I didn't realize theat the man page was that broken.  It doesn't even mention
the main effect of -f -- to ignore errors for nonexistent files.  This is
discussed in the COMPATIBILITY section, with quite bad wording:

% COMPATIBILITY
%      The rm utility differs from historical implementations in that the -f
%      option only masks attempts to remove non-existent files instead of mask-
%      ing a large variety of errors.  The -v option is non-standard and its use
%      in scripts is not recommended.

"masks attempts to remove" is strange wording.  rm doesn't attempt to
remove nonexistent files; it attempts to remove existent files ...

The code doesn't do anything like that.  It is close to POSIX, and just
tries to remove existent files and then ignores the ENOENT error for
nonexistent files iff -f.

These bugs haven't changed since FreeBSD-1 (Net/2?).  They are only in
the man page.  The change to POSIX conformance is documented in the
FreeBSD-1 version:

%%%
/*
  * rm --
  *	This rm is different from historic rm's, but is expected to match
  *	POSIX 1003.2 behavior.  The most visible difference is that -f
  *	has two specific effects now, ignore non-existent files and force
  * 	file removal.
  */
%%%

This hasn't changed, and neither has the man page which apparently
documents a version before this.

I think it is misleading to say "force file removal".  I still tend to
think of the f in rm -f being "force".  That seems to have been last
correct in 1988 (?) before Net/2.  All f does is to force is turn off
some checking and interactivity.  It doesn't do things like clobbering
immutable flags so that unlink() can work.

Bruce


More information about the svn-src-all mailing list