aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPerttu Ahola <celeron55@gmail.com>2011-12-04 12:49:58 +0200
committerPerttu Ahola <celeron55@gmail.com>2011-12-04 12:49:58 +0200
commitab67985d21ddac57591ec7a5062c323e7dfbdc32 (patch)
tree2ed528b96c35209f619dafbe52cd0f2b3e9f7525 /src
parentbc5cc638fc510f55237d51eb031fa5f18b3f7a04 (diff)
downloadminetest-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.cpp33
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);