diff options
Diffstat (limited to 'src/stat_cache.c')
-rw-r--r-- | src/stat_cache.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/src/stat_cache.c b/src/stat_cache.c index 9db1d210..ed212927 100644 --- a/src/stat_cache.c +++ b/src/stat_cache.c @@ -1265,10 +1265,12 @@ stat_cache_entry * stat_cache_get_entry(const buffer * const name) { /* Note: paths are expected to be normalized before calling stat_cache, * e.g. without repeated '/' */ + #ifndef _WIN32 if (name->ptr[0] != '/') { errno = EINVAL; return NULL; } + #endif /* * check if the directory for this file has changed @@ -1319,17 +1321,35 @@ stat_cache_entry * stat_cache_get_entry(const buffer * const name) { } struct stat st; + #ifdef _WIN32 + if (final_slash && len < 4096) { + char buf[4096]; + memcpy(buf, name->ptr, len); + buf[len] = '\0'; + if (-1 == stat(buf, &st)) { + return NULL; + } + /* must check since stat() w/o trailing '/' above */ + if (S_ISREG(st.st_mode)) { + errno = ENOTDIR; + return NULL; + } + } + else + #endif if (-1 == stat(name->ptr, &st)) { return NULL; } if (NULL == sce) { + #ifdef _WIN32 /*(already checked above)*/ /* fix broken stat/open for symlinks to reg files with appended slash on freebsd,osx */ if (final_slash && S_ISREG(st.st_mode)) { errno = ENOTDIR; return NULL; } + #endif sce = stat_cache_entry_init(); buffer_copy_string_len(&sce->name, name->ptr, len); |