From 7a6e548690b116878070665bd9844275823bb730 Mon Sep 17 00:00:00 2001
From: Bernhard Voelker <mail@bernhard-voelker.de>
Date: Wed, 2 Nov 2016 07:32:01 +0100
Subject: [PATCH 080/224] find: handle more readdir(3) errors

Similar to the FTS readdir fix in v4.6.0-72-g155c9d1, handle the last
two unhandled readdir(3) errors.

* find/pred.c (pred_empty): Do the above.
* lib/fdleak.c (get_proc_max_fd): Likewise.  While at it, fix the
condition to only skip "." and ".."; previously, also other files
beginning with ".." would have been skipped - that was theoretically,
as we only expect the FD files in "/proc/self/fd".
---
 find/pred.c  | 10 ++++++++++
 lib/fdleak.c | 21 +++++++++++++++++----
 2 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/find/pred.c b/find/pred.c
index f7e9b59c..c064606d 100644
--- a/find/pred.c
+++ b/find/pred.c
@@ -380,6 +380,9 @@ pred_empty (const char *pathname, struct stat *stat_buf, struct predicate *pred_
 	  state.exit_status = 1;
 	  return false;
 	}
+      /* errno is not touched in the loop body, so initializing it here
+       * once before the loop is enough to detect readdir(3) errors.  */
+      errno = 0;
       for (dp = readdir (d); dp; dp = readdir (d))
 	{
 	  if (dp->d_name[0] != '.'
@@ -390,6 +393,13 @@ pred_empty (const char *pathname, struct stat *stat_buf, struct predicate *pred_
 	      break;
 	    }
 	}
+      if (errno)
+	{
+	  /* Handle errors from readdir(3). */
+	  error (0, errno, "%s", safely_quote_err_filename (0, pathname));
+	  state.exit_status = 1;
+	  return false;
+	}
       if (CLOSEDIR (d))
 	{
 	  error (0, errno, "%s", safely_quote_err_filename (0, pathname));
diff --git a/lib/fdleak.c b/lib/fdleak.c
index 5dc4cb1e..cf19fa26 100644
--- a/lib/fdleak.c
+++ b/lib/fdleak.c
@@ -19,6 +19,7 @@
 
 /* system headers. */
 #include <assert.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <limits.h>
 #include <poll.h>
@@ -77,11 +78,23 @@ get_proc_max_fd (void)
       int good = 0;
       struct dirent *dent;
 
-      while ((dent=readdir (dir)) != NULL)
-	{
+      while (1)
+        {
+	  errno = 0;
+	  dent = readdir (dir);
+	  if (NULL == dent)
+	    {
+	      if (errno)
+		{
+		  error (0, errno, "%s", quotearg_n_style (0, locale_quoting_style, path));
+		  good = 0;
+		}
+	      break;
+	    }
+
 	  if (dent->d_name[0] != '.'
-	      || (dent->d_name[0] != 0
-		  && dent->d_name[1] != 0 && dent->d_name[1] != '.'))
+	      || (dent->d_name[1] != 0
+		  && (dent->d_name[1] != '.' || dent->d_name[2] != 0)))
 	    {
 	      const int fd = safe_atoi (dent->d_name, literal_quoting_style);
 	      if (fd > maxfd)
-- 
2.19.1

