findutils/findutils-4.5.8-0003-27a7e4...

108 lines
3.6 KiB
Diff

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;