* 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.
This commit is contained in:
		| @@ -1,3 +1,12 @@ | |||||||
|  | 2008-11-28  Christian Franke  <franke@computer.org> | ||||||
|  |  | ||||||
|  | 	* 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  <me+cygwin@cgf.cx> | 2008-11-27  Christopher Faylor  <me+cygwin@cgf.cx> | ||||||
|  |  | ||||||
| 	* exceptions.cc (sigpacket::process): Make sure that 'tls' is never | 	* exceptions.cc (sigpacket::process): Make sure that 'tls' is never | ||||||
|   | |||||||
| @@ -93,6 +93,9 @@ readdir_worker (DIR *dir, dirent *de) | |||||||
|     } |     } | ||||||
|  |  | ||||||
|   de->d_ino = 0; |   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); |   int res = ((fhandler_base *) dir->__fh)->readdir (dir, de); | ||||||
|  |  | ||||||
|   if (res == ENMFILE) |   if (res == ENMFILE) | ||||||
|   | |||||||
| @@ -1677,6 +1677,20 @@ fhandler_disk_file::readdir_helper (DIR *dir, dirent *de, DWORD w32_err, | |||||||
|       dir->__flags &= ~dirent_set_d_ino; |       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 |   /* Check for directory reparse point.  These are potential volume mount | ||||||
|      points which have another inode than the underlying directory. */ |      points which have another inode than the underlying directory. */ | ||||||
|   if ((attr & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT)) |   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); | 	  path_conv fpath (&fbuf, PC_SYM_NOFOLLOW); | ||||||
| 	  if (fpath.issymlink () || fpath.is_fs_special ()) | 	  if (fpath.issymlink () || fpath.is_fs_special ()) | ||||||
| 	    fname->Length -= 4 * sizeof (WCHAR); | 	    { | ||||||
|  | 	      fname->Length -= 4 * sizeof (WCHAR); | ||||||
|  | 	      de->d_type = DT_UNKNOWN; | ||||||
|  | 	    } | ||||||
| 	} | 	} | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -18,11 +18,13 @@ | |||||||
|  |  | ||||||
| #pragma pack(push,4) | #pragma pack(push,4) | ||||||
| #if defined(__INSIDE_CYGWIN__) || defined (__CYGWIN_USE_BIG_TYPES__) | #if defined(__INSIDE_CYGWIN__) || defined (__CYGWIN_USE_BIG_TYPES__) | ||||||
|  | #define _DIRENT_HAVE_D_TYPE | ||||||
| struct dirent | struct dirent | ||||||
| { | { | ||||||
|   long __d_version;			/* Used internally */ |   long __d_version;			/* Used internally */ | ||||||
|   __ino64_t d_ino; |   __ino64_t d_ino; | ||||||
|   __uint32_t __d_unused1; |   unsigned char d_type; | ||||||
|  |   unsigned char __d_unused1[3]; | ||||||
|   __uint32_t __d_internal1; |   __uint32_t __d_internal1; | ||||||
|   char d_name[NAME_MAX + 1]; |   char d_name[NAME_MAX + 1]; | ||||||
| }; | }; | ||||||
| @@ -77,7 +79,7 @@ int scandir (const char *__dir, | |||||||
| 	     int (*compar) (const struct dirent **, const struct dirent **)); | 	     int (*compar) (const struct dirent **, const struct dirent **)); | ||||||
|  |  | ||||||
| int alphasort (const struct dirent **__a, const struct dirent **__b); | 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'.  */ | /* File types for `d_type'.  */ | ||||||
| enum | enum | ||||||
| { | { | ||||||
| @@ -104,6 +106,6 @@ enum | |||||||
| /* Convert between stat structure types and directory types.  */ | /* Convert between stat structure types and directory types.  */ | ||||||
| # define IFTODT(mode)		(((mode) & 0170000) >> 12) | # define IFTODT(mode)		(((mode) & 0170000) >> 12) | ||||||
| # define DTTOIF(dirtype)        ((dirtype) << 12) | # define DTTOIF(dirtype)        ((dirtype) << 12) | ||||||
| #endif /* #if 0 */ | #endif /* _DIRENT_HAVE_D_TYPE */ | ||||||
| #endif /* _POSIX_SOURCE */ | #endif /* _POSIX_SOURCE */ | ||||||
| #endif /*_SYS_DIRENT_H*/ | #endif /*_SYS_DIRENT_H*/ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user