summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Munro2022-07-22 04:57:12 +0000
committerThomas Munro2022-07-22 04:57:12 +0000
commit9d3444dcce4d62716edec9c58c1b40be42185e7b (patch)
tree9e7176e919fec1b0e083d58efd6747639eaf1b0a
parent44ccdce514c4b3b92c8aca744e9cf7be4580be0b (diff)
Fix get_dirent_type() for Windows junction points.
Commit 87e6ed7c8 added code that intended to report Windows "junction points" as DT_LNK (the same way we report symlinks on Unix). Windows junction points are *also* directories according to the Windows attributes API, and we were reporting them as as DT_DIR. Change the order we check the attribute flags, to prioritize DT_LNK. If at some point we start using Windows' recently added real symlinks and need to distinguish them from junction points, we may need to rethink this, but for now this continues the tradition of wrapper functions that treat junction points as symlinks. Back-patch to 14, where get_dirent_type() landed. Reviewed-by: Michael Paquier <[email protected]> Reviewed-by: Alvaro Herrera <[email protected]> Discussion: https://postgr.es/m/CA%2BhUKGLzLK4PUPx0_AwXEWXOYAejU%3D7XpxnYE55Y%2Be7hB2N3FA%40mail.gmail.com Discussion: https://postgr.es/m/20220721111751.x7hod2xgrd76xr5c%40alvherre.pgsql
-rw-r--r--src/port/dirent.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/src/port/dirent.c b/src/port/dirent.c
index f67bbf7f71..10ea4bdd42 100644
--- a/src/port/dirent.c
+++ b/src/port/dirent.c
@@ -106,13 +106,17 @@ 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))
+
+ /*
+ * For reparse points dwReserved0 field will contain the ReparseTag. We
+ * check this first, because reparse points are also reported as
+ * directories.
+ */
+ if ((fd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0 &&
+ (fd.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT))
d->ret.d_type = DT_LNK;
+ else if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
+ d->ret.d_type = DT_DIR;
else
d->ret.d_type = DT_REG;