diff --git a/simgear/compiler.h b/simgear/compiler.h index 939d9f31..e29a20e3 100644 --- a/simgear/compiler.h +++ b/simgear/compiler.h @@ -67,6 +67,7 @@ # define vsnprintf _vsnprintf # endif # define copysign _copysign +# define strcasecmp stricmp # pragma warning(disable: 4786) // identifier was truncated to '255' characters # pragma warning(disable: 4244) // conversion from double to float diff --git a/simgear/misc/sg_dir.cxx b/simgear/misc/sg_dir.cxx index 74b493ed..92e5af6f 100644 --- a/simgear/misc/sg_dir.cxx +++ b/simgear/misc/sg_dir.cxx @@ -29,6 +29,8 @@ # include #endif +#include + #include #include @@ -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; }