Module: wine
Branch: master
Commit: 54a471732fd8f99175118a7064caeeda5869dd58
URL: http://source.winehq.org/git/wine.git/?a=commit;h=54a471732fd8f99175118a706…
Author: Ken Thomases <ken(a)codeweavers.com>
Date: Fri Oct 5 10:48:55 2007 -0500
ntdll: Work around a bug in Mac OS X's getdirentries().
---
dlls/ntdll/directory.c | 24 ++++++++++++++++++++++--
1 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
index d4ccf5f..894d336 100644
--- a/dlls/ntdll/directory.c
+++ b/dlls/ntdll/directory.c
@@ -1174,6 +1174,26 @@ done:
#elif defined HAVE_GETDIRENTRIES
/***********************************************************************
+ * wine_getdirentries
+ *
+ * Wrapper for the BSD getdirentries system call to fix a bug in the
+ * Mac OS X version. For some file systems (at least Apple Filing
+ * Protocol a.k.a. AFP), getdirentries resets the file position to 0
+ * when it's about to return 0 (no more entries). So, a subsequent
+ * getdirentries call starts over at the beginning again, causing an
+ * infinite loop.
+ */
+static inline int wine_getdirentries(int fd, char *buf, int nbytes, long *basep)
+{
+ int res = getdirentries(fd, buf, nbytes, basep);
+#ifdef __APPLE__
+ if (res == 0)
+ lseek(fd, *basep, SEEK_SET);
+#endif
+ return res;
+}
+
+/***********************************************************************
* read_directory_getdirentries
*
* Read a directory using the BSD getdirentries system call; helper for NtQueryDirectoryFile.
@@ -1203,7 +1223,7 @@ static int read_directory_getdirentries( int fd, IO_STATUS_BLOCK *io, void *buff
io->u.Status = STATUS_SUCCESS;
/* FIXME: should make sure size is larger than filesystem block size */
- res = getdirentries( fd, data, size, &restart_pos );
+ res = wine_getdirentries( fd, data, size, &restart_pos );
if (res == -1)
{
io->u.Status = FILE_GetNtStatus();
@@ -1306,7 +1326,7 @@ static int read_directory_getdirentries( int fd, IO_STATUS_BLOCK *io, void *buff
restart_last_info = last_info;
restart_info_pos = io->Information;
restart:
- res = getdirentries( fd, data, size, &restart_pos );
+ res = wine_getdirentries( fd, data, size, &restart_pos );
de = (struct dirent *)data;
}