aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-03-14 03:23:56 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-03-14 03:23:56 +0000
commit00f7db376cb3b0176de738d9f9c172397771fbd8 (patch)
tree9766226a065ac37bcaceeb5fe6bd23353862a6a4
parentb48ef1382f57e4a89a28382f60d09236d328fece (diff)
downloadruby-00f7db376cb3b0176de738d9f9c172397771fbd8.tar.gz
dir.h: direct::d_type
* dir.c (glob_helper): use d_type to reduce lstat system calls. * win32/dir.h (struct direct): add d_type instead of d_isdir and d_isrep. SYMLINKD is unreliable, since the target can be replaced after a link was created. * win32/win32.c (readdir_internal): set d_type. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49966 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog10
-rw-r--r--dir.c4
-rw-r--r--win32/dir.h8
-rw-r--r--win32/win32.c9
4 files changed, 25 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 2b22b77d10..9aa9ec2805 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Sat Mar 14 12:23:53 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * dir.c (glob_helper): use d_type to reduce lstat system calls.
+
+ * win32/dir.h (struct direct): add d_type instead of d_isdir and
+ d_isrep. SYMLINKD is unreliable, since the target can be
+ replaced after a link was created.
+
+ * win32/win32.c (readdir_internal): set d_type.
+
Sat Mar 14 02:14:50 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
* parse.y (primary): empty parentheses at cmdarg can be null.
diff --git a/dir.c b/dir.c
index 8e7f1c945b..2a7ffc9909 100644
--- a/dir.c
+++ b/dir.c
@@ -1731,13 +1731,13 @@ glob_helper(
name = buf + pathlen + (dirsep != 0);
if (recursive && dotfile < ((flags & FNM_DOTMATCH) ? 2 : 1)) {
/* RECURSIVE never match dot files unless FNM_DOTMATCH is set */
-#ifndef _WIN32
+#ifndef DT_DIR
if (do_lstat(buf, &st, flags, enc) == 0)
new_isdir = S_ISDIR(st.st_mode) ? YES : S_ISLNK(st.st_mode) ? UNKNOWN : NO;
else
new_isdir = NO;
#else
- new_isdir = dp->d_isdir ? (!dp->d_isrep ? YES : UNKNOWN) : NO;
+ new_isdir = dp->d_type == DT_DIR ? YES : dp->d_type == DT_LNK ? UNKNOWN : NO;
#endif
}
diff --git a/win32/dir.h b/win32/dir.h
index 5a97f54623..04d87ebabc 100644
--- a/win32/dir.h
+++ b/win32/dir.h
@@ -8,6 +8,11 @@
# endif
#endif
+#define DT_UNKNOWN 0
+#define DT_DIR (S_IFDIR>>12)
+#define DT_REG (S_IFREG>>12)
+#define DT_LNK 10
+
struct direct
{
long d_namlen;
@@ -15,8 +20,7 @@ struct direct
char *d_name;
char *d_altname; /* short name */
short d_altlen;
- char d_isdir; /* directory */
- char d_isrep; /* reparse point */
+ uint8_t d_type;
};
typedef struct {
WCHAR *start;
diff --git a/win32/win32.c b/win32/win32.c
index 73163f6171..d2fde0751e 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -2139,8 +2139,13 @@ readdir_internal(DIR *dirp, BOOL (*conv)(const WCHAR *, const WCHAR *, struct di
//
// Attributes
//
- dirp->dirstr.d_isdir = GetBit(dirp->bits, BitOfIsDir(dirp->loc));
- dirp->dirstr.d_isrep = GetBit(dirp->bits, BitOfIsRep(dirp->loc));
+ /* ignore FILE_ATTRIBUTE_DIRECTORY as unreliable for reparse points */
+ if (GetBit(dirp->bits, BitOfIsRep(dirp->loc)))
+ dirp->dirstr.d_type = DT_LNK;
+ else if (GetBit(dirp->bits, BitOfIsDir(dirp->loc)))
+ dirp->dirstr.d_type = DT_DIR;
+ else
+ dirp->dirstr.d_type = DT_REG;
//
// Now set up for the next call to readdir