summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorGurusamy Sarathy <gsar@cpan.org>1999-05-03 18:48:25 +0000
committerGurusamy Sarathy <gsar@cpan.org>1999-05-03 18:48:25 +0000
commite1dbac945fcdd357e211833376769053fa9ffc60 (patch)
treefde359e4e64eb62476246d08d7c7b796e5f7342c /win32
parent1236053a2c722e2b9e93af4bb14c92036416d727 (diff)
downloadperl-e1dbac945fcdd357e211833376769053fa9ffc60.tar.gz
adjust win32_stat() to cope with FindFirstFile() and stat() bugs
(makes opendir(D,"c:") work reliably) p4raw-id: //depot/perl@3300
Diffstat (limited to 'win32')
-rw-r--r--win32/win32.c34
1 files changed, 22 insertions, 12 deletions
diff --git a/win32/win32.c b/win32/win32.c
index fe621d1ecc..df28419105 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -896,30 +896,40 @@ DllExport int
win32_stat(const char *path, struct stat *buffer)
{
char t[MAX_PATH+1];
- const char *p = path;
int l = strlen(path);
int res;
if (l > 1) {
switch(path[l - 1]) {
+ /* FindFirstFile() and stat() are buggy with a trailing
+ * backslash, so change it to a forward slash :-( */
case '\\':
- case '/':
- if (path[l - 2] != ':') {
- strncpy(t, path, l - 1);
- t[l - 1] = 0;
- p = t;
- };
+ strncpy(t, path, l-1);
+ t[l - 1] = '/';
+ t[l] = '\0';
+ path = t;
+ break;
+ /* FindFirstFile() is buggy with "x:", so add a slash :-( */
+ case ':':
+ if (l == 2 && isALPHA(path[0])) {
+ t[0] = path[0]; t[1] = ':'; t[2] = '/'; t[3] = '\0';
+ l = 3;
+ path = t;
+ }
+ break;
}
}
- res = stat(p,buffer);
+ res = stat(path,buffer);
if (res < 0) {
/* CRT is buggy on sharenames, so make sure it really isn't.
* XXX using GetFileAttributesEx() will enable us to set
* buffer->st_*time (but note that's not available on the
* Windows of 1995) */
- DWORD r = GetFileAttributes(p);
+ DWORD r = GetFileAttributes(path);
if (r != 0xffffffff && (r & FILE_ATTRIBUTE_DIRECTORY)) {
- buffer->st_mode |= S_IFDIR | S_IREAD;
+ /* buffer may still contain old garbage since stat() failed */
+ Zero(buffer, 1, struct stat);
+ buffer->st_mode = S_IFDIR | S_IREAD;
errno = 0;
if (!(r & FILE_ATTRIBUTE_READONLY))
buffer->st_mode |= S_IWRITE | S_IEXEC;
@@ -927,8 +937,8 @@ win32_stat(const char *path, struct stat *buffer)
}
}
else {
- if (l == 3 && path[l-2] == ':'
- && (path[l-1] == '\\' || path[l-1] == '/'))
+ if (l == 3 && isALPHA(path[0]) && path[1] == ':'
+ && (path[2] == '\\' || path[2] == '/'))
{
/* The drive can be inaccessible, some _stat()s are buggy */
if (!GetVolumeInformation(path,NULL,0,NULL,NULL,NULL,NULL,0)) {