bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#12339: Bug: rm -fr . doesn't dir depth first deletion yet it is docu


From: Linda Walsh
Subject: bug#12339: Bug: rm -fr . doesn't dir depth first deletion yet it is documented to do so.
Date: Fri, 07 Sep 2012 08:02:58 -0700
User-agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.24) Gecko/20100228 Lightning/0.9 Thunderbird/2.0.0.24 Mnenhy/0.7.6.666



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':







reply via email to

[Prev in Thread] Current Thread [Next in Thread]