From 616eba62a637b9b7440680d9ca4490d36347be46 Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Thu, 3 Sep 2020 13:09:52 +1200 Subject: [PATCH v3 2/3] Add d_type to Win32 dirent port. MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit The member d_type is a BSD/GNU extension to struct dirent, but Windows has the information required to populate it so let's add it to our emulation so that get_dirent_type() can use it. Author: Juan José Santamaría Flecha Discussion: https://postgr.es/m/CA%2BhUKG%2BFzxupGGN4GpUdbzZN%2Btn6FQPHo8w0Q%2BAPH5Wz8RG%2Bww%40mail.gmail.com --- src/include/port/win32_msvc/dirent.h | 23 +++++++++++++++++++++++ src/port/dirent.c | 15 +++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/include/port/win32_msvc/dirent.h b/src/include/port/win32_msvc/dirent.h index 9fabdf332b..6a54f964f5 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,26 @@ DIR *opendir(const char *); struct dirent *readdir(DIR *); int closedir(DIR *); +/* File types for 'd_type'. */ +enum + { + DT_UNKNOWN = 0, +# define DT_UNKNOWN DT_UNKNOWN + DT_FIFO = 1, +# define DT_FIFO DT_FIFO + DT_CHR = 2, +# define DT_CHR DT_CHR + DT_DIR = 4, +# define DT_DIR DT_DIR + DT_BLK = 6, +# define DT_BLK DT_BLK + DT_REG = 8, +# define DT_REG DT_REG + DT_LNK = 10, +# define DT_LNK DT_LNK + DT_SOCK = 12, +# define DT_SOCK DT_SOCK + DT_WHT = 14 +# define DT_WHT DT_WHT + }; #endif diff --git a/src/port/dirent.c b/src/port/dirent.c index b264484fca..519dd82101 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; } @@ -77,6 +78,7 @@ struct dirent * readdir(DIR *d) { WIN32_FIND_DATA fd; + DWORD attrib; if (d->handle == INVALID_HANDLE_VALUE) { @@ -105,6 +107,19 @@ 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 identifed types are: directory, regular file or symbolic link. + * Errors are treated as a file type that could not be determined. + */ + attrib = GetFileAttributes(d->ret.d_name); + if (attrib == INVALID_FILE_ATTRIBUTES) + d->ret.d_type = DT_UNKNOWN; + else if ((attrib & FILE_ATTRIBUTE_DIRECTORY) != 0) + d->ret.d_type = DT_DIR; + else if ((attrib & FILE_ATTRIBUTE_REPARSE_POINT) != 0) + d->ret.d_type = DT_LNK; + else + d->ret.d_type = DT_REG; return &d->ret; } -- 2.20.1