* lib/fts.c (fts_open): Revert to FTS_NOCHDIR mode whenever the openat emulation has to save and restore the working directory, not merely when "." cannot be opened. This is what the removed FIXME comment suggested. On such platforms FTS_CWDFD costs a save_cwd/fchdir/restore_cwd round trip per entry visited, and is no more robust than FTS_NOCHDIR, since the emulation resolves fts_cwd_fd by name anyway.
Signed-off-by: Oleg Tolmatcev <[email protected]> --- ChangeLog | 7 +++++++ lib/fts.c | 33 ++++----------------------------- 2 files changed, 11 insertions(+), 29 deletions(-) On Windows with a native grep this gave a speedup of up to 50% on a large directory. diff --git a/ChangeLog b/ChangeLog index 2254b198b1..52247f8913 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2026-09-04 Oleg Tolmatcev <[email protected]> + + fts: don't use FTS_CWDFD where openat is emulated via fchdir + * lib/fts.c (fts_open): Revert to FTS_NOCHDIR mode whenever the + openat emulation has to save and restore the working directory, + not merely when "." cannot be opened. + 2026-08-27 Bruno Haible <[email protected]> tests: Check that c32isprint is consistent with isprint in the C locale. diff --git a/lib/fts.c b/lib/fts.c index d7265ed292..0c03c8141e 100644 --- a/lib/fts.c +++ b/lib/fts.c @@ -381,36 +381,11 @@ fts_open (char * const *argv, /* Initialize fts_cwd_fd. */ sp->fts_cwd_fd = AT_FDCWD; - if ( ISSET(FTS_CWDFD) && ! HAVE_OPENAT_SUPPORT) + if ( ISSET(FTS_CWDFD) && ! HAVE_OPENAT_SUPPORT + && openat_needs_fchdir ()) { - /* While it isn't technically necessary to open "." this - early, doing it here saves us the trouble of ensuring - later (where it'd be messier) that "." can in fact - be opened. If not, revert to FTS_NOCHDIR mode. */ - int fd = open (".", O_SEARCH | O_CLOEXEC); - if (fd < 0) - { - /* Even if "." is unreadable, don't revert to FTS_NOCHDIR mode - on systems like Linux+PROC_FS, where our openat emulation - is good enough. Note: on a system that emulates - openat via /proc, this technique can still fail, but - only in extreme conditions, e.g., when the working - directory cannot be saved (i.e. save_cwd fails) -- - and that happens on Linux only when "." is unreadable - and the CWD would be longer than PATH_MAX. - FIXME: once Linux kernel openat support is well established, - replace the above open call and this entire if/else block - with the body of the if-block below. */ - if ( openat_needs_fchdir ()) - { - SET(FTS_NOCHDIR); - CLR(FTS_CWDFD); - } - } - else - { - close (fd); - } + SET(FTS_NOCHDIR); + CLR(FTS_CWDFD); } /* -- 2.55.0.windows.5
