From: Perttu Ahola Date: Sun, 4 Dec 2011 10:49:58 +0000 (+0200) Subject: Add support for unix filesystems which yield DT_UNKNOWN in dirent->d_type, falling... X-Git-Url: http://81.2.79.47:8989/gitweb/?a=commitdiff_plain;h=ab67985d21ddac57591ec7a5062c323e7dfbdc32;p=zefram%2Fminetest%2Fminetest_engine.git Add support for unix filesystems which yield DT_UNKNOWN in dirent->d_type, falling back on stat(). --- diff --git a/src/filesys.cpp b/src/filesys.cpp index 99a0a6ef..4a01becb 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);