From 1f0f557cdccdfcdd671b90bcdaaca7c686df19cf Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 18 May 2010 13:03:48 +0200 Subject: [PATCH 3/5] 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. --- ChangeLog | 10 ++++++++++ NEWS | 11 +++++++++++ find/ftsfind.c | 37 +++++++++++++++++++------------------ 3 files changed, 40 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index e0a4573..432a6bb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2010-04-10 James Youngman + 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 853fade..b46fdd3 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,17 @@ GNU findutils NEWS - User visible changes. -*- outline -*- (allout) -uid, -used, -atime, -mtime, -ctime. #27017: find -D opt / -fstype ext3 -print , -quit coredumps +#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). + ** Translations Updated the Dutch, Polish, French, Czech, Indonesian, Chinese diff --git a/find/ftsfind.c b/find/ftsfind.c index cc54c9f..26392ce 100644 --- a/find/ftsfind.c +++ b/find/ftsfind.c @@ -518,24 +518,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. */ @@ -585,8 +567,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; -- 1.6.6.1