From 87e6ed7c8c6abb6dd62119259d2fd89169a04ac0 Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Mon, 7 Sep 2020 23:18:22 +1200 Subject: [PATCH] Add d_type to our Windows dirent emulation. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows us to skip some stat calls, by extending commit 861c6e7c to cover Windows systems. Author: Juan José Santamaría Flecha Reviewed-by: Alvaro Herrera Reviewed-by: Andres Freund Reviewed-by: Magnus Hagander Reviewed-by: Thomas Munro Discussion: https://postgr.es/m/CA%2BhUKG%2BFzxupGGN4GpUdbzZN%2Btn6FQPHo8w0Q%2BAPH5Wz8RG%2Bww%40mail.gmail.com --- src/include/port/win32_msvc/dirent.h | 11 +++++++++++ src/port/dirent.c | 10 ++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/include/port/win32_msvc/dirent.h b/src/include/port/win32_msvc/dirent.h index 9fabdf332b..62799db001 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 b264484fca..70a444f9a5 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; }