summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHadrien <hadrien@psydk.org>2019-07-29 08:04:22 +0200
committerHadrien <hadrien@psydk.org>2019-07-29 15:02:26 +0200
commite02c5ef48ac50f66d7702e4be19282122acf1b0d (patch)
tree7c8822d55c31c29ea75fb663074115f9f8d5d21d
parent331a703f5d2b1b47c4b8312971c44ed2faae505e (diff)
Optimize DirAccessUnix::get_next() for some file systems
On some file systems, like ext4 on Linux, readdir() gives enough information to determine the entry type in order to avoid doing a stat() system call. Use this information and call stat() only if necessary: for file systems that do not support this feature and for links.
-rw-r--r--drivers/unix/dir_access_unix.cpp31
1 files changed, 13 insertions, 18 deletions
diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp
index 251bab5783..6817137a94 100644
--- a/drivers/unix/dir_access_unix.cpp
+++ b/drivers/unix/dir_access_unix.cpp
@@ -126,37 +126,32 @@ String DirAccessUnix::get_next() {
if (!dir_stream)
return "";
- dirent *entry;
- entry = readdir(dir_stream);
+ dirent *entry = readdir(dir_stream);
if (entry == NULL) {
-
list_dir_end();
return "";
}
- //typedef struct stat Stat;
- struct stat flags;
-
String fname = fix_unicode_name(entry->d_name);
- String f = current_dir.plus_file(fname);
-
- if (stat(f.utf8().get_data(), &flags) == 0) {
-
- if (S_ISDIR(flags.st_mode)) {
-
- _cisdir = true;
-
+ // Look at d_type to determine if the entry is a directory, unless
+ // its type is unknown (the file system does not support it) or if
+ // the type is a link, in that case we want to resolve the link to
+ // known if it points to a directory. stat() will resolve the link
+ // for us.
+ if (entry->d_type == DT_UNKNOWN || entry->d_type == DT_LNK) {
+ String f = current_dir.plus_file(fname);
+
+ struct stat flags;
+ if (stat(f.utf8().get_data(), &flags) == 0) {
+ _cisdir = S_ISDIR(flags.st_mode);
} else {
-
_cisdir = false;
}
-
} else {
-
- _cisdir = false;
+ _cisdir = (entry->d_type == DT_DIR);
}
_cishidden = (fname != "." && fname != ".." && fname.begins_with("."));