From 6df7f712278544950c964d415a8bb555c2f342aa Mon Sep 17 00:00:00 2001 From: corinna Date: Fri, 28 Nov 2008 09:04:34 +0000 Subject: [PATCH] * 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/ChangeLog | 9 +++++++++ winsup/cygwin/dir.cc | 3 +++ winsup/cygwin/fhandler_disk_file.cc | 19 ++++++++++++++++++- winsup/cygwin/include/sys/dirent.h | 8 +++++--- 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index adbcbaa454..22fc998dea 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,12 @@ +2008-11-28 Christian Franke + + * 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. + 2008-11-27 Christopher Faylor * exceptions.cc (sigpacket::process): Make sure that 'tls' is never diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc index 30662e6d4e..2b9125f0be 100644 --- a/winsup/cygwin/dir.cc +++ b/winsup/cygwin/dir.cc @@ -93,6 +93,9 @@ readdir_worker (DIR *dir, dirent *de) } de->d_ino = 0; + de->d_type = DT_UNKNOWN; + memset (&de->__d_unused1, 0, sizeof (de->__d_unused1)); + int res = ((fhandler_base *) dir->__fh)->readdir (dir, de); if (res == ENMFILE) diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index c388a13622..ac7ee2ee8f 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; + } } } diff --git a/winsup/cygwin/include/sys/dirent.h b/winsup/cygwin/include/sys/dirent.h index 41bfcc11db..451c802bcb 100644 --- a/winsup/cygwin/include/sys/dirent.h +++ b/winsup/cygwin/include/sys/dirent.h @@ -18,11 +18,13 @@ #pragma pack(push,4) #if defined(__INSIDE_CYGWIN__) || defined (__CYGWIN_USE_BIG_TYPES__) +#define _DIRENT_HAVE_D_TYPE struct dirent { long __d_version; /* Used internally */ __ino64_t d_ino; - __uint32_t __d_unused1; + unsigned char d_type; + unsigned char __d_unused1[3]; __uint32_t __d_internal1; char d_name[NAME_MAX + 1]; }; @@ -77,7 +79,7 @@ int scandir (const char *__dir, int (*compar) (const struct dirent **, const struct dirent **)); int alphasort (const struct dirent **__a, const struct dirent **__b); -#if 0 /* these make no sense in the absence of d_type */ +#ifdef _DIRENT_HAVE_D_TYPE /* File types for `d_type'. */ enum { @@ -104,6 +106,6 @@ enum /* Convert between stat structure types and directory types. */ # define IFTODT(mode) (((mode) & 0170000) >> 12) # define DTTOIF(dirtype) ((dirtype) << 12) -#endif /* #if 0 */ +#endif /* _DIRENT_HAVE_D_TYPE */ #endif /* _POSIX_SOURCE */ #endif /*_SYS_DIRENT_H*/ -- 2.11.0