Sophie

Sophie

distrib > Fedora > 13 > i386 > media > updates-src > by-pkgid > e5760cbf312a51afcbaf16ccc5c78b75 > files > 11

findutils-4.4.2-8.fc13.src.rpm

 ChangeLog      |   10 ++++++++++
 NEWS           |   15 +++++++++++++++
 find/ftsfind.c |   37 +++++++++++++++++++------------------
 3 files changed, 44 insertions(+), 18 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index fefc1b8..98d7962 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2010-04-10  James Youngman  <jay@gnu.org>
 
+	Fix Savannah bug #19593, -execdir .... {} + has suboptimal performance
+	* find/ftsfind.c (consider_visiting): Don't call
+	complete_pending_execdirs for every file we visit.
+	(find): Instead, call complete_pending_execdirs every time we
+	see a file which isn't at the same nesting level as the previous
+	file we saw.  This is an improvement but not optimal (since
+	descending into a subdirectory will cause us to issue an exec
+	before we've finished with the current directory).
+	* NEWS: Mention this change.
+
 	Exec predicates now store which directory they want to run in.
 	* lib/dircallback.c (run_in_dirfd): New name for old run_in_dir
 	function.
diff --git a/NEWS b/NEWS
index 6b8b725..569ff51 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,20 @@
 GNU findutils NEWS - User visible changes.	-*- outline -*- (allout)
 
+* Major changes in release 4.4.3-git, YYYY-MM-DD
+
+** Bug Fixes
+
+#19593: -execdir .... {} + has suboptimal performance (see below)
+
+** Performance changes
+
+The find program will once again build argument lists longer than 1
+with "-execdir ...+".  The upper limit of 1 argument for execdir was
+introduced as a workaround in findutils-4.3.4.   The limit is now
+removed, but find still does not issue the maximum possible number of
+arguments, since an exec will occur each time find encounters a
+subdirectory (if at least one argument is pending).
+
 * Major changes in release 4.4.2, 2009-11-26
 
 ** Functional Enhancements to find
diff --git a/find/ftsfind.c b/find/ftsfind.c
index 9945abd..3c9ae1d 100644
--- a/find/ftsfind.c
+++ b/find/ftsfind.c
@@ -524,24 +524,6 @@ consider_visiting(FTS *p, FTSENT *ent)
       visit(p, ent, &statbuf);
     }
 
-  /* XXX: if we allow a build-up of pending arguments for "-execdir foo {} +" 
-   * we need to execute them in the same directory as we found the item.  
-   * If we are trying to do "find a -execdir echo {} +", we will need to 
-   * echo 
-   *      a while in the original working directory
-   *      b while in a
-   *      c while in b (just before leaving b)
-   *
-   * These restrictions are hard to satisfy while using fts().   The reason is
-   * that it doesn't tell us just before we leave a directory.  For the moment, 
-   * we punt and don't allow the arguments to build up.
-   */
-  if (state.execdirs_outstanding)
-    {
-      show_outstanding_execdirs(stderr);
-      complete_pending_execdirs ();
-    }
-
   if (ent->fts_info == FTS_DP)
     {
       /* we're leaving a directory. */
@@ -591,8 +573,27 @@ find(char *arg)
     }
   else
     {
+      int level = INT_MIN;
+
       while ( (ent=fts_read(p)) != NULL )
 	{
+	  if (state.execdirs_outstanding)
+	    {
+	      /* If we changed level, perform any outstanding
+	       * execdirs.  If we see a sequence of directory entries
+	       * like this: fffdfffdfff, we could build a command line
+	       * of 9 files, but this simple-minded implementation
+	       * builds a command line for only 3 files at a time
+	       * (since fts descends into the directories).
+	       */
+	      if ((int)ent->fts_level != level)
+		{
+		  show_outstanding_execdirs (stderr);
+		  complete_pending_execdirs ();
+		}
+	    }
+	  level = (int)ent->fts_level;
+
 	  state.have_stat = false;
 	  state.have_type = false;
 	  state.type = 0;