On 06/22/2016 03:01 PM, Pádraig Brady wrote: > It'll need this on top, to better differentiate FTS_ERR and FTS_DNR, > as fts_build may be called multiple times for the same dir.
Hmm, but rm(1) won't show the errno. I'm getting better results with the attached, i.e., handling the readdir() failure like the other failures way down and setting the FTS_STOP flag. With Peter's LD_PRELOAD lib, I'm getting this: $ LD_PRELOAD=/tmp/libfake_readdir.so ~/findutils/find/find /tmp/ddd /tmp/ddd Forcing failure of readdir /home/berny/findutils/find/find: failed to read file names from \ file system at or below ‘/tmp/ddd’: Too many levels of symbolic links $ LD_PRELOAD=/tmp/libfake_readdir.so ~/coreutils/src/rm -rfv /tmp/ddd Forcing failure of readdir Forcing failure of readdir /home/berny/coreutils/src/rm: fts_read failed: Too many levels of \ symbolic links WDYT? Have a nice day, Berny
diff --git a/lib/fts.c b/lib/fts.c index bcdcff9..42863fe 100644 --- a/lib/fts.c +++ b/lib/fts.c @@ -1461,9 +1461,20 @@ fts_build (register FTS *sp, int type) while (cur->fts_dirp) { bool is_dir; size_t d_namelen; + __set_errno (0); struct dirent *dp = readdir(cur->fts_dirp); - if (dp == NULL) + if (dp == NULL) { + if (errno) { + saved_errno = errno; + fts_lfree(head); + closedir_and_clear(cur->fts_dirp); + cur->fts_info = FTS_ERR; + SET(FTS_STOP); + __set_errno (saved_errno); + return (NULL); + } break; + } if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name)) continue;