summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorAlex Davies <alex.davies@talktalk.net>2010-09-29 08:29:55 -0700
committerFather Chrysostomos <sprout@cpan.org>2010-09-29 08:29:55 -0700
commit525f9ba8587889fcdd36dd0cc8fcd3e8ab3b1e51 (patch)
treedb3ba3f4162f1ebccb944f82bb7b362c9dda222b /win32
parentf51599d95895bcc29a1e0f5b9109d175790a5110 (diff)
downloadperl-525f9ba8587889fcdd36dd0cc8fcd3e8ab3b1e51.tar.gz
[perl #71714] Remove redundant stat from Win32's opendir()
Here's a patch that removes an unnecesary call to win32_stat() by the opendir code on Win32. This provides a noticeable speed up when recursively traversing a directory eg. calls to File::Find::find(). Note it does change behaviour in the following cases: 1. The patch makes directory names longer than MAX_PATH fail and sets errno to ENAMETOOLONG ("Filename too long"). Currently, in this case errno is not actually set in win32_opendir. 2. If the directory is actually a regular file then currently errno is not set, and so (as in case 1) errno ends up being set to EBADF. The patched version will 'fail' via the same code path as if it's just a non existant file/directory name (FindFirstFile will return ERROR_PATH_NOT_FOUND) and so errno gets set to ENOENT.
Diffstat (limited to 'win32')
-rw-r--r--win32/win32.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/win32/win32.c b/win32/win32.c
index b33f732a82..2b6c3bdc52 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -849,7 +849,6 @@ win32_opendir(const char *filename)
long len;
long idx;
char scanname[MAX_PATH+3];
- Stat_t sbuf;
WIN32_FIND_DATAA aFindData;
WIN32_FIND_DATAW wFindData;
bool using_wide;
@@ -857,12 +856,24 @@ win32_opendir(const char *filename)
char *ptr;
len = strlen(filename);
- if (len > MAX_PATH)
+ if (len == 0) {
+ errno = ENOENT;
return NULL;
-
- /* check to see if filename is a directory */
- if (win32_stat(filename, &sbuf) < 0 || !S_ISDIR(sbuf.st_mode))
+ }
+ if (len > MAX_PATH) {
+ errno = ENAMETOOLONG;
return NULL;
+ }
+
+#if 0 /* This call to stat is unnecessary. The FindFirstFile() below will
+ * fail with ERROR_PATH_NOT_FOUND if filename is not a directory. */
+ {
+ /* check to see if filename is a directory */
+ Stat_t sbuf;
+ if (win32_stat(filename, &sbuf) < 0 || !S_ISDIR(sbuf.st_mode))
+ return NULL;
+ }
+#endif
/* Get us a DIR structure */
Newxz(dirp, 1, DIR);