diff options
author | Thomas Munro | 2020-09-07 11:18:22 +0000 |
---|---|---|
committer | Thomas Munro | 2020-09-07 11:38:19 +0000 |
commit | 87e6ed7c8c6abb6dd62119259d2fd89169a04ac0 (patch) | |
tree | e9b67810f70146301f93d9fe6a1a91a6803ae480 | |
parent | 74ff28197c14de0aa709497ce707e31bb9af7253 (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.h | 11 | ||||
-rw-r--r-- | src/port/dirent.c | 10 |
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; } |