GNU bug report logs -
#12339
Bug: rm -fr . doesn't dir depth first deletion yet it is documented to do so.
Previous Next
Reported by: Linda Walsh <coreutils <at> tlinx.org>
Date: Mon, 3 Sep 2012 00:34:02 UTC
Severity: normal
Done: Assaf Gordon <assafgordon <at> gmail.com>
Bug is archived. No further changes may be made.
Full log
Message #173 received at 12339 <at> debbugs.gnu.org (full text, mbox):
Eric Blake wrote:
>
> Then set up a shell alias or a wrapper script that comes first in your
> $PATH. Then it is under your explicit control, while the default is
> still appropriate for everyone else.
>
> Just because the defaults don't match your expectations doesn't mean you
> can't change the behavior _on your system_ to avoid extra typing on your
> part.
---
Doesn't work for programs that need to call rm to remove all files
in a dir.
And I already have changed default behavior on MY systems.
I already added the patch below -- that only does my behavior if the
user isn't running in POSIXLY_CORRECT mode.
Now it's certainly easier to set an env var 1 place to control script
behavior than making changes in all the places...
I'm just trying to get the env var in so I don't have to distribute
a version of rm with my scripts that works.
-----
--- src/remove.c 2011-10-10 00:56:46.000000000 -0700
+++ src/remove.c.new 2012-09-06 14:28:07.816810683 -0700
@@ -173,6 +173,35 @@
}
}
+
+/* separate functions to check for next part of file name being dotdot or...*/
+
+static inline bool
+dotdot (char const *file_name)
+{
+ if (file_name[0] == '.' && file_name[1])
+ {
+ char sep = file_name[(file_name[1] == '.') + 1];
+ return (! sep || ISSLASH (sep));
+ }
+ else
+ return false;
+}
+
+/* dot */
+
+static inline bool
+dot (char const * file_name)
+{
+ if (file_name[0] == '.')
+ {
+ char sep = file_name[1];
+ return (! sep || ISSLASH(sep));
+ }
+ else
+ return false;
+}
+
/* Prompt whether to remove FILENAME (ent->, if required via a combination of
the options specified by X and/or file attributes. If the file may
be removed, return RM_OK. If the user declines to remove the file,
@@ -203,6 +232,7 @@
int dirent_type = is_dir ? DT_DIR : DT_UNKNOWN;
int write_protected = 0;
+ int special_delete_content = 0;
/* When nonzero, this indicates that we failed to remove a child entry,
either because the user declined an interactive prompt, or due to
@@ -222,7 +252,11 @@
wp_errno = errno;
}
- if (write_protected || x->interactive == RMI_ALWAYS)
+ if (!x->posix_correctly && dot(filename) && !x->force)
+ special_delete_content = 1;
+
+
+ if (write_protected || x->interactive == RMI_ALWAYS || special_delete_content)
{
if (0 <= write_protected && dirent_type == DT_UNKNOWN)
{
@@ -281,11 +315,16 @@
if (dirent_type == DT_DIR
&& mode == PA_DESCEND_INTO_DIR
&& !is_empty)
- fprintf (stderr,
- (write_protected
- ? _("%s: descend into write-protected directory %s? ")
- : _("%s: descend into directory %s? ")),
- program_name, quoted_name);
+ {
+ char * action = special_delete_content
+ ?
_("delete contents of")
+ :
_("descend into");
+ fprintf (stderr,
+
(write_protected
+ ?
_("%s: %s write-protected directory %s? ")
+ :
_("%s: %s directory %s? ")),
+ action,
program_name, quoted_name);
+ }
else
{
if (cache_fstatat (fd_cwd, filename, sbuf, AT_SYMLINK_NOFOLLOW) != 0)
@@ -476,7 +515,8 @@
/* 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)))
+ if ( (x->posix_correctly ? dot_or_dotdot : dotdot)
+ (last_component
(ent->fts_accpath)))
{
error (0, 0, _("cannot remove directory: %s"),
quote (ent->fts_path));
--- src/remove.h 2011-07-28 03:38:27.000000000 -0700
+++ src/remove.h 2012-09-06 13:33:01.282362765 -0700
@@ -34,6 +34,14 @@
/* If true, ignore nonexistent files. */
bool ignore_missing_files;
+ /* true if force (-f) was specified indicating user knows what they
+ * are doing and don't want to questioned or see errors from command */
+ bool force;
+
+ /* true for users wanting strict posix compliance of more flexible, lax,
+ * or useful behaviors */
+ bool posix_correctly;
+
/* If true, query the user about whether to remove each file. */
enum rm_interactive interactive;
--- src/rm.c 2011-10-02 02:20:54.000000000 -0700
+++ src/rm.c 2012-09-06 13:33:04.132500554 -0700
@@ -206,6 +206,7 @@
bool preserve_root = true;
struct rm_options x;
bool prompt_once = false;
+ x.posix_correctly = (getenv ("POSIXLY_CORRECT") != NULL );
int c;
initialize_main (&argc, &argv);
@@ -222,10 +226,11 @@
{
switch (c)
{
- case 'f':
+ case 'f': /* suppress warnings/errors */
x.interactive = RMI_NEVER;
x.ignore_missing_files = true;
prompt_once = false;
+ x.force = true;
break;
case 'i':
This bug report was last modified 6 years and 186 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.