bug#15926: RFE: unlink command already uses 'unlink' call; make 'rm' use 'remove' call
On 11/19/2013 11:45 PM, Bernhard Voelker wrote: On 11/20/2013 03:19 AM, Eric Blake wrote: Yes, the 'rm -rf .' case appears to be a regression in coreutils that is contrary to the behavior required by POSIX. That is: $ mkdir /tmp/foo /tmp/foo/sub $ cd /tmp/foo $ rm -r . rm: cannot remove directory: ‘.’ $ ls sub appears to be a bug in current coreutils, because it should have successfully called rmdir(sub) prior to failing on the attempt to rmdir(.). I disagree: see at the top of: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/rm.html If either of the files dot or dot-dot are specified as the basename portion of an operand (that is, the final pathname component) or if an operand resolves to the root directory, rm shall write a diagnostic message to standard error and do nothing more with such operands. Ah, that's where it is. I was looking in the numbered steps, not the paragraph before the numbered steps. So it appears that coreutils is compliant after all. Maybe cannot remove directory is a bit weak - it's more like refusing to remove dot|dot-dot|root directory. Indeed, a clearer error message would be possible. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
bug#15926: RFE: unlink command already uses 'unlink' call; make 'rm' use 'remove' call
On 11/20/2013 02:44 PM, Eric Blake wrote: On 11/19/2013 11:45 PM, Bernhard Voelker wrote: Maybe cannot remove directory is a bit weak - it's more like refusing to remove dot|dot-dot|root directory. Indeed, a clearer error message would be possible. What about the following? $ src/rm -r src/. src/rm: refusing to remove '.' or '..' directory: skipping 'src/.' I didn't want to explicitly mention POSIX here ... it's just to clarify that rm(1) does not swallow errors from the kernel like EPERM, etc. The texinfo file is enhanced in the patch below, too. Have a nice day, Berny From f85ec85852ea62e4fe4510044ffb4b31880a6b7c Mon Sep 17 00:00:00 2001 From: Bernhard Voelker m...@bernhard-voelker.de Date: Thu, 21 Nov 2013 00:47:36 +0100 Subject: [PATCH] doc: enhance diagnostic when rm skips . or .. arguments The error diagnostic rm: cannot remove directory: '.' does not give the user a hint for the reason. Issue a clearer error message. * src/remove.c (rm_fts): Enhance the error diagnostic in the above case to emphasize that skipping is done deliberately. In the corresponding comment, mention that POSIX mandates this behavior. Likewise in the subsequent comment for skipping /. * doc/coreutils.texi (rm invocation): In the paragraph describing the above behavior, mention that POSIX mandates it. --- doc/coreutils.texi | 3 ++- src/remove.c | 12 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/doc/coreutils.texi b/doc/coreutils.texi index 035f2e6..64713dc 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -9281,7 +9281,8 @@ the @option{-f} or @option{--force} option is not given, or the If the response is not affirmative, the file is skipped. Any attempt to remove a file whose last file name component is -@file{.} or @file{..} is rejected without any prompting. +@file{.} or @file{..} is rejected without any prompting, as mandated +by POSIX. @emph{Warning}: If you use @command{rm} to remove a file, it is usually possible to recover the contents of that file. If you want more assurance diff --git a/src/remove.c b/src/remove.c index cdbbec5..3d386cf 100644 --- a/src/remove.c +++ b/src/remove.c @@ -437,17 +437,21 @@ rm_fts (FTS *fts, FTSENT *ent, struct rm_options const *x) /* Perform checks that can apply only for command-line arguments. */ if (ent-fts_level == FTS_ROOTLEVEL) { - /* If the basename of a command line argument is . or .., + /* POSIX says: + If the basename of a command line argument is . or .., diagnose it and do nothing more with that argument. */ if (dot_or_dotdot (last_component (ent-fts_accpath))) { - error (0, 0, _(cannot remove directory: %s), - quote (ent-fts_path)); + error (0, 0, + _(refusing to remove %s or %s directory: skipping %s), + quote_n (0, .), quote_n (1, ..), + quote_n (2, ent-fts_path)); fts_skip_tree (fts, ent); return RM_ERROR; } - /* If a command line argument resolves to / (and --preserve-root + /* POSIX also says: + If a command line argument resolves to / (and --preserve-root is in effect -- default) diagnose and skip it. */ if (ROOT_DEV_INO_CHECK (x-root_dev_ino, ent-fts_statp)) { -- 1.8.3.1
bug#15926: RFE: unlink command already uses 'unlink' call; make 'rm' use 'remove' call
On 20/11/2013 16:03, Bernhard Voelker wrote: $ src/rm -r src/. src/rm: refusing to remove '.' or '..' directory: skipping 'src/.' That gets back to what Bob mentioned about it being a nanny-restriction. The inevitable comment to be asked by someone is Refuse? Isn't it my computer? How do I override such a refusal? I seem to remember reading that the -f flag was specifically added to override such such a refusal w/no further comment. Answer: well, yeah it was, but they caught MS-itus, and wanted to put in are you really sure? (y/[n]), but weren't allowed to ask more questions, so it just wins because its not your system anymore. **- Is it true that you can override this with -supercalifragilisticexpialidocious flag? 1/2:-) I still think an ENV flag that lists the command and behavior to override would be a specific enough, yet generally enough solution to safely make a case for allowing it. I.e. _EXPERT_=rm(.) command(feature1 feature2) find(.error)
bug#15943: [PATCH] doc: enhance diagnostic when rm skips . or .. arguments
On 20/11/2013 15:47, Bernhard Voelker wrote: - /* If a command line argument resolves to / (and --preserve-root + /* POSIX also says: + If a command line argument resolves to / (and --preserve-root is in effect -- default) diagnose and skip it. */ if (ROOT_DEV_INO_CHECK (x-root_dev_ino, ent-fts_statp)) { - So it is easier to delete everything under '/' than under /tmp/. Hmm... Maybe since '/' doesn't really delete the file system itself, but only files and dirs underneath '/', Then the correct solution is if a user says to remove /tmp/ it will remove everything under /tmp but not /tmp itself? That doesn't seem to be disallowed by POSIX... (its a bit absurd, but as long as it conforms to POSIX it should be fine, right? ;-/)
bug#15926: RFE: unlink command already uses 'unlink' call; make 'rm' use 'remove' call
On 11/20/2013 05:03 PM, Bernhard Voelker wrote: On 11/20/2013 02:44 PM, Eric Blake wrote: On 11/19/2013 11:45 PM, Bernhard Voelker wrote: Maybe cannot remove directory is a bit weak - it's more like refusing to remove dot|dot-dot|root directory. Indeed, a clearer error message would be possible. What about the following? $ src/rm -r src/. src/rm: refusing to remove '.' or '..' directory: skipping 'src/.' That helps. But I'm also starting to think we should add a new long option --no-preserve-dot, similar to how --no-preserve-root can be used to work around the restriction. Then people that want to can create an alias or other wrapper around rm to get the non-nanny behavior, while the default behavior still complies with POSIX. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
bug#15926: RFE: unlink command already uses 'unlink' call; make 'rm' use 'remove' call
On 11/20/2013 05:48 PM, Linda Walsh wrote: I still think an ENV flag that lists the command Environment variables that modify behavior are nasty, and should generally be avoided when simpler solutions exist. In this case, I'd much rather add a long option, 'rm --no-preserve-dot', and let you write an alias or other wrapper when you want the non-default behavior. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
bug#15943: [PATCH] doc: enhance diagnostic when rm skips . or .. arguments
forcemerge 15943 15926 thanks On 11/20/2013 05:54 PM, Linda Walsh wrote: On 20/11/2013 15:47, Bernhard Voelker wrote: - /* If a command line argument resolves to / (and --preserve-root + /* POSIX also says: + If a command line argument resolves to / (and No need to spawn a new bug when the existing bug tracking the issue is still under discussion. And on the surface, this email has nothing to do with the subject line of enhance diagnostic when rm skips . or .. arguments. Maybe since '/' doesn't really delete the file system itself, but only files and dirs underneath '/', Huh? When POSIX-compliant (that is, when --preserve-root is in effect), attempting to 'rm -r /' does nothing at all. When bypassing POSIX (with 'rm -r --no-preserve-root'), rm will delete as much as possible, and eventually fail once it has deleted system resources that were essential to the correct operation of the computer; but if you can get far enough, it would eventually attempt rm(/). Then the correct solution is if a user says to remove /tmp/ it will remove everything under /tmp but not /tmp itself? That doesn't seem to be disallowed by POSIX... Not true. POSIX requires 'rm -r /tmp/' to attempt to delete /tmp, but that it might fail to do so if nested files are not deleted (perhaps due to ownership) or if the user doesn't have rights to delete /tmp. (its a bit absurd, but as long as it conforms to POSIX it should be fine, right? ;-/) Your idea of skipping the attempt to delete /tmp would not conform with POSIX. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
bug#15926: RFE: unlink command already uses 'unlink' call; make 'rm' use 'remove' call
On 11/21/2013 01:48 AM, Linda Walsh wrote: Isn't it my computer? How do I override such a refusal? That riddle isn't too hard, is it? ;-) POSIX (and common sense) forbids to remove something ending on .. Therefore just use the canonicalized name, e.g.: $ mkdir /tmp/xx $ cd /tmp/xx $ rm -rv . rm: refusing to remove ‘.’ or ‘..’ directory: skipping ‘.’ $ rm -rv $(pwd -P) removed directory: ‘/tmp/xx’ or alternatively (just the rm invocation): $ rm -rv $(readlink -f .) removed directory: ‘/tmp/xx’ As you were mentioning MS: the above obviously won't probably work in Cygwin as the underlying (file) system may return EBUSY. Have a nice day, Berny
bug#15926: RFE: unlink command already uses 'unlink' call; make 'rm' use 'remove' call
On 11/21/2013 03:07 AM, Eric Blake wrote: On 11/20/2013 05:03 PM, Bernhard Voelker wrote: What about the following? $ src/rm -r src/. src/rm: refusing to remove '.' or '..' directory: skipping 'src/.' That helps. Thanks, I'll push it unless someone comes up with a better wording. But I'm also starting to think we should add a new long option --no-preserve-dot, similar to how --no-preserve-root can be used to work around the restriction. Then people that want to can create an alias or other wrapper around rm to get the non-nanny behavior, while the default behavior still complies with POSIX. Admittedly, compared to the academic question behind --no-preserve-root (which is like what happens to me when the globe under my feet disappears?), there may be more real-world reasons to remove .. However, as it's possible to pass the canonicalized file name of . or .. to rm(1), I'm not yet convinced that it warrants adding a new --no-preserve-dot-or-dotdot (and for symmetry reasons a new --preserve-dot-or-dotdot) option. Have a nice day, Berny