]> git.mxchange.org Git - simgear.git/commitdiff
On Unix, check for symlinks from readdir(), and look through them (using stat())...
authorJames Turner <zakalawe@mac.com>
Wed, 21 Jul 2010 21:08:06 +0000 (22:08 +0100)
committerJames Turner <zakalawe@mac.com>
Wed, 21 Jul 2010 21:08:06 +0000 (22:08 +0100)
simgear/misc/sg_dir.cxx

index 74b493edf95f8b07054b6d540816bf8bfff04641..92e5af6f56799bbccd18278140b243e3bafdf8ba 100644 (file)
@@ -29,6 +29,8 @@
 #  include <dirent.h>
 #endif
 
+#include <sys/stat.h>
+
 #include <simgear/debug/logstream.hxx>
 
 #include <cstring>
@@ -110,8 +112,26 @@ PathList Dir::children(int types, const std::string& nameFilter) const
     if (!(types & INCLUDE_HIDDEN) && (entry->d_name[0] == '.')) {
       continue;
     }
-        
-    if (entry->d_type == DT_DIR) {
+    
+    int type = entry->d_type;
+    if (type == DT_LNK) {
+      // find symlink target type using stat()
+      struct stat s;
+      if (stat(file(entry->d_name).c_str(), &s)) {
+        continue; // stat() failed
+      }
+      
+      if (S_ISDIR(s.st_mode)) {
+        type = DT_DIR;
+      } else if (S_ISREG(s.st_mode)) {
+        type = DT_REG;
+      } else {
+        // symlink to block/fifo/char file, ignore
+        continue;
+      }
+    } // of symlink look-through
+    
+    if (type == DT_DIR) {
       if (!(types & TYPE_DIR)) {
         continue;
       }
@@ -121,7 +141,7 @@ PathList Dir::children(int types, const std::string& nameFilter) const
           continue;
         }
       }
-    } else if (entry->d_type == DT_REG) {
+    } else if (type == DT_REG) {
       if (!(types & TYPE_FILE)) {
         continue;
       }