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;
 

Reply via email to