From 9a3f97994bbbd10e8a476e3aed40320d9ed05101 Mon Sep 17 00:00:00 2001
From: Dmitry Kalinkin <dmitry.kalinkin@gmail.com>
Date: Tue, 12 May 2020 16:41:13 -0400
Subject: [PATCH] Directory: implement error reporting

---
 Directory.cxx    | 35 +++++++++++++++++++++++++++++++----
 Directory.hxx.in |  5 +++--
 2 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/Directory.cxx b/Directory.cxx
index d6409484..be9158ea 100644
--- a/Directory.cxx
+++ b/Directory.cxx
@@ -103,7 +103,7 @@ void Directory::Clear()
 
 namespace KWSYS_NAMESPACE {
 
-bool Directory::Load(const std::string& name)
+bool Directory::Load(const std::string& name, std::string* errorMessage)
 {
   this->Clear();
 #  if (defined(_MSC_VER) && _MSC_VER < 1300) || defined(__BORLANDC__)
@@ -146,7 +146,8 @@ bool Directory::Load(const std::string& name)
   return _findclose(srchHandle) != -1;
 }
 
-unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
+unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name,
+                                                     std::string* errorMessage)
 {
 #  if (defined(_MSC_VER) && _MSC_VER < 1300) || defined(__BORLANDC__)
   // Older Visual C++ and Embarcadero compilers.
@@ -192,6 +193,8 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
 #  include <sys/types.h>
 
 #  include <dirent.h>
+#  include <errno.h>
+#  include <string.h>
 
 // PGI with glibc has trouble with dirent and large file support:
 //  http://www.pgroup.com/userforum/viewtopic.php?
@@ -209,29 +212,46 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
 
 namespace KWSYS_NAMESPACE {
 
-bool Directory::Load(const std::string& name)
+bool Directory::Load(const std::string& name, std::string* errorMessage)
 {
   this->Clear();
 
+  errno = 0;
   DIR* dir = opendir(name.c_str());
 
   if (!dir) {
+    if (errorMessage != nullptr) {
+      *errorMessage = std::string(strerror(errno));
+    }
     return false;
   }
 
+  errno = 0;
   for (kwsys_dirent* d = readdir(dir); d; d = readdir(dir)) {
     this->Internal->Files.emplace_back(d->d_name);
   }
+  if (errno != 0) {
+    if (errorMessage != nullptr) {
+      *errorMessage = std::string(strerror(errno));
+    }
+    return false;
+  }
+
   this->Internal->Path = name;
   closedir(dir);
   return true;
 }
 
-unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
+unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name,
+                                                     std::string* errorMessage)
 {
+  errno = 0;
   DIR* dir = opendir(name.c_str());
 
   if (!dir) {
+    if (errorMessage != nullptr) {
+      *errorMessage = std::string(strerror(errno));
+    }
     return 0;
   }
 
@@ -239,6 +259,13 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
   for (kwsys_dirent* d = readdir(dir); d; d = readdir(dir)) {
     count++;
   }
+  if (errno != 0) {
+    if (errorMessage != nullptr) {
+      *errorMessage = std::string(strerror(errno));
+    }
+    return false;
+  }
+
   closedir(dir);
   return count;
 }
diff --git a/Directory.hxx.in b/Directory.hxx.in
index 9b0f4c33..7bc9db02 100644
--- a/Directory.hxx.in
+++ b/Directory.hxx.in
@@ -35,7 +35,7 @@ public:
    * in that directory. 0 is returned if the directory can not be
    * opened, 1 if it is opened.
    */
-  bool Load(const std::string&);
+  bool Load(const std::string&, std::string* errorMessage = nullptr);
 
   /**
    * Return the number of files in the current directory.
@@ -46,7 +46,8 @@ public:
    * Return the number of files in the specified directory.
    * A higher performance static method.
    */
-  static unsigned long GetNumberOfFilesInDirectory(const std::string&);
+  static unsigned long GetNumberOfFilesInDirectory(
+    const std::string&, std::string* errorMessage = nullptr);
 
   /**
    * Return the file at the given index, the indexing is 0 based
-- 
GitLab