From ab67985d21ddac57591ec7a5062c323e7dfbdc32 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sun, 4 Dec 2011 12:49:58 +0200 Subject: [PATCH] Add support for unix filesystems which yield DT_UNKNOWN in dirent->d_type, falling back on stat(). --- src/filesys.cpp | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/filesys.cpp b/src/filesys.cpp index 99a0a6ef8..4a01becbf 100644 --- a/src/filesys.cpp +++ b/src/filesys.cpp @@ -190,10 +190,35 @@ std::vector GetDirListing(std::string pathstring) if(dirp->d_name[0]!='.'){ DirListNode node; node.name = dirp->d_name; - if(dirp->d_type == DT_DIR) node.dir = true; - else node.dir = false; - if(node.name != "." && node.name != "..") - listing.push_back(node); + if(node.name == "." || node.name == "..") + continue; + + int isdir = -1; // -1 means unknown + + /* + POSIX doesn't define d_type member of + struct dirent and certain filesystems on + glibc/Linux will only return DT_UNKNOWN for + the d_type member. + */ +#ifdef _DIRENT_HAVE_D_TYPE + if(dirp->d_type != DT_UNKNOWN) + isdir = (dirp->d_type == DT_DIR); +#endif /* _DIRENT_HAVE_D_TYPE */ + + /* + Was d_type DT_UNKNOWN (or nonexistent)? + If so, try stat(). + */ + if(isdir == -1) + { + struct stat statbuf; + if (stat((pathstring + "/" + node.name).c_str(), &statbuf)) + continue; + isdir = ((statbuf.st_mode & S_IFDIR) == S_IFDIR); + } + node.dir = isdir; + listing.push_back(node); } } closedir(dp);