diff options
author | Alex Davies <alex.davies@talktalk.net> | 2010-09-29 08:29:55 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2010-09-29 08:29:55 -0700 |
commit | 525f9ba8587889fcdd36dd0cc8fcd3e8ab3b1e51 (patch) | |
tree | db3ba3f4162f1ebccb944f82bb7b362c9dda222b /win32 | |
parent | f51599d95895bcc29a1e0f5b9109d175790a5110 (diff) | |
download | perl-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.c | 21 |
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); |