summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Munro2020-09-07 11:18:22 +0000
committerThomas Munro2020-09-07 11:38:19 +0000
commit87e6ed7c8c6abb6dd62119259d2fd89169a04ac0 (patch)
treee9b67810f70146301f93d9fe6a1a91a6803ae480
parent74ff28197c14de0aa709497ce707e31bb9af7253 (diff)
Add d_type to our Windows dirent emulation.
This allows us to skip some stat calls, by extending commit 861c6e7c to cover Windows systems. Author: Juan José Santamaría Flecha <[email protected]> Reviewed-by: Alvaro Herrera <[email protected]> Reviewed-by: Andres Freund <[email protected]> Reviewed-by: Magnus Hagander <[email protected]> Reviewed-by: Thomas Munro <[email protected]> Discussion: https://postgr.es/m/CA%2BhUKG%2BFzxupGGN4GpUdbzZN%2Btn6FQPHo8w0Q%2BAPH5Wz8RG%2Bww%40mail.gmail.com
-rw-r--r--src/include/port/win32_msvc/dirent.h11
-rw-r--r--src/port/dirent.c10
2 files changed, 21 insertions, 0 deletions
diff --git a/src/include/port/win32_msvc/dirent.h b/src/include/port/win32_msvc/dirent.h
index 9fabdf332b2..62799db0014 100644
--- a/src/include/port/win32_msvc/dirent.h
+++ b/src/include/port/win32_msvc/dirent.h
@@ -10,6 +10,7 @@ struct dirent
{
long d_ino;
unsigned short d_reclen;
+ unsigned char d_type;
unsigned short d_namlen;
char d_name[MAX_PATH];
};
@@ -20,4 +21,14 @@ DIR *opendir(const char *);
struct dirent *readdir(DIR *);
int closedir(DIR *);
+/* File types for 'd_type'. */
+#define DT_UNKNOWN 0
+#define DT_FIFO 1
+#define DT_CHR 2
+#define DT_DIR 4
+#define DT_BLK 6
+#define DT_REG 8
+#define DT_LNK 10
+#define DT_SOCK 12
+#define DT_WHT 14
#endif
diff --git a/src/port/dirent.c b/src/port/dirent.c
index b264484fca2..70a444f9a53 100644
--- a/src/port/dirent.c
+++ b/src/port/dirent.c
@@ -69,6 +69,7 @@ opendir(const char *dirname)
d->handle = INVALID_HANDLE_VALUE;
d->ret.d_ino = 0; /* no inodes on win32 */
d->ret.d_reclen = 0; /* not used on win32 */
+ d->ret.d_type = DT_UNKNOWN;
return d;
}
@@ -105,6 +106,15 @@ readdir(DIR *d)
}
strcpy(d->ret.d_name, fd.cFileName); /* Both strings are MAX_PATH long */
d->ret.d_namlen = strlen(d->ret.d_name);
+ /* The only identified types are: directory, regular file or symbolic link */
+ if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
+ d->ret.d_type = DT_DIR;
+ /* For reparse points dwReserved0 field will contain the ReparseTag */
+ else if ((fd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0 &&
+ (fd.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT))
+ d->ret.d_type = DT_LNK;
+ else
+ d->ret.d_type = DT_REG;
return &d->ret;
}