From fa421c7a751ebde2acc62dcf032fb3b36f698db1 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 28 Nov 2008 09:04:35 +0000 Subject: * dir.cc (readdir_worker): Initialize dirent.d_type and __d_unused1. * fhandler_disk_file.cc (fhandler_disk_file::readdir_helper): Set dirent.d_type based on FILE_ATTRIBUTE_*. * include/sys/dirent.h: Define _DIRENT_HAVE_D_TYPE (enables DT_* declarations). (struct dirent): Add d_type. Adjust __d_unused1 size to preserve layout. --- winsup/cygwin/fhandler_disk_file.cc | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'winsup/cygwin/fhandler_disk_file.cc') diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index c388a1362..ac7ee2ee8 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -1677,6 +1677,20 @@ fhandler_disk_file::readdir_helper (DIR *dir, dirent *de, DWORD w32_err, dir->__flags &= ~dirent_set_d_ino; } + /* Set d_type if type can be determined from file attributes. + FILE_ATTRIBUTE_SYSTEM ommitted to leave DT_UNKNOWN for old symlinks. + For new symlinks, d_type will be reset to DT_UNKNOWN below. */ + if (attr && + !(attr & ( ~FILE_ATTRIBUTE_VALID_FLAGS + | FILE_ATTRIBUTE_SYSTEM + | FILE_ATTRIBUTE_REPARSE_POINT))) + { + if (attr & FILE_ATTRIBUTE_DIRECTORY) + de->d_type = DT_DIR; + else + de->d_type = DT_REG; + } + /* Check for directory reparse point. These are potential volume mount points which have another inode than the underlying directory. */ if ((attr & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT)) @@ -1728,7 +1742,10 @@ fhandler_disk_file::readdir_helper (DIR *dir, dirent *de, DWORD w32_err, } path_conv fpath (&fbuf, PC_SYM_NOFOLLOW); if (fpath.issymlink () || fpath.is_fs_special ()) - fname->Length -= 4 * sizeof (WCHAR); + { + fname->Length -= 4 * sizeof (WCHAR); + de->d_type = DT_UNKNOWN; + } } } -- cgit v1.2.3