bug-findutils
[Top][All Lists]
Advanced

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

Re: [Findutils-patches] [PATCH] -delete requires -depth


From: Bruno De Fraine
Subject: Re: [Findutils-patches] [PATCH] -delete requires -depth
Date: Sun, 26 Aug 2007 19:51:31 +0200

On 23 Aug 2007, at 14:59, Eric Blake wrote:
Bruno also had the idea of letting -delete operate
without -depth, by letting -delete swap the traversal of that subtree to
depth-first while the rest of the traversal is breadth-first prior to
encountering the -delete action.

Actually, not quite. My proposal amounted to exactly the following:

--- findutils-4.3.8/find/parser.c 2007-06-09 14:12:06.000000000 +0200
+++ findutils-mod/find/parser.c 2007-08-24 12:08:07.000000000 +0200
@@ -724,7 +724,7 @@
   our_pred = insert_primary (entry);
   our_pred->side_effects = our_pred->no_default_print = true;
-  /* -delete implies -depth */
-  options.do_dir_first = false;

   /* We do not need stat information because we check for the case
    * (errno==EISDIR) in pred_delete.

The idea is to have a very straightforward -delete: the action will try to delete the nodes in order, the traversal is not modified in any way. The main benefit over other proposals is that -delete can be combined with normal traversal (and thus with pruning). For example, consider:

$ ../findutils-mod/find/find
.
./aa
./aa/.svn
./aa/.svn/foo
./aa/foo
./bb
./bb/foo
./.svn
./.svn/foo
$ ../findutils-mod/find/find -not "(" -name .svn -prune ")" -name foo -delete
$ ../findutils-mod/find/find
.
./aa
./aa/.svn
./aa/.svn/foo
./bb
./.svn
./.svn/foo

The user will have to make sure that nodes can actually be deleted during the traversal, otherwise he will receive an error. When deleting directories, this means that the directory must be empty. If he wants to delete an entire directory tree as a part of one and the same traversal, he will need to use -depth, but at least he will knowingly change the traversal order then.

Also, after deleting a directory in a normal traversal, find should not try to visit this directory anymore, because it's gone. The user could accomplish this by including a -prune after the -delete, or find could do it automatically, with a change like this:

--- findutils-4.3.8/find/pred.c 2007-06-09 14:12:35.000000000 +0200
+++ findutils-mod/find/pred.c   2007-08-26 19:30:45.000000000 +0200
@@ -392,6 +392,8 @@
        flags |= AT_REMOVEDIR;
       if (perform_delete(flags))
        {
+         if (options.do_dir_first == true && (flags & AT_REMOVEDIR))
+         state.stop_at_current_level = true;
          return true;
        }
       else
@@ -403,7 +405,11 @@
/* unlink() operation failed because we should have done rmdir(). */
                  flags |= AT_REMOVEDIR;
                  if (perform_delete(flags))
+                 {
+ if (options.do_dir_first == true && (flags & AT_REMOVEDIR))
+                   state.stop_at_current_level = true;
                    return true;
+                 }
                }
            }
        }

As such it is possible to -delete empty directories in a normal traversal. For example, consider the following to clean empty subdirectories in a tree:

$ ../findutils-mod/find/find
.
./aa
./aa/foo
./bb
./cc
$ ../findutils-mod/find/find -type d
.
./aa
./aa/foo
./cc
$ ../findutils-mod/find/find -type d -empty -delete
$ ../findutils-mod/find/find
.
./aa
./bb


Regards,
Bruno De Fraine




reply via email to

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