diff options
author | Perttu Ahola <celeron55@gmail.com> | 2011-12-04 12:49:58 +0200 |
---|---|---|
committer | Perttu Ahola <celeron55@gmail.com> | 2011-12-04 12:49:58 +0200 |
commit | ab67985d21ddac57591ec7a5062c323e7dfbdc32 (patch) | |
tree | 2ed528b96c35209f619dafbe52cd0f2b3e9f7525 /src | |
parent | bc5cc638fc510f55237d51eb031fa5f18b3f7a04 (diff) | |
download | minetest-ab67985d21ddac57591ec7a5062c323e7dfbdc32.tar.gz minetest-ab67985d21ddac57591ec7a5062c323e7dfbdc32.tar.bz2 minetest-ab67985d21ddac57591ec7a5062c323e7dfbdc32.zip |
Add support for unix filesystems which yield DT_UNKNOWN in dirent->d_type, falling back on stat().
Diffstat (limited to 'src')
-rw-r--r-- | src/filesys.cpp | 33 |
1 files 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<DirListNode> 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); |