From 9e24b8ace9ef4865df9e1f2f23313be45abeca21 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Thu, 11 Sep 2003 23:30:26 +0000 Subject: [PATCH] * fhandler_disk_file.cc (path_conv::ndisk_links): Rename from num_entries. Accept an argument and calculate any extra links needed based on missing . and .. entries. (fhandler_disk_file::fstat_helper): Always call pc->ndisks_links() to calculate the number of links. * path.h (path_conv::ndisk_links): Declare. --- winsup/cygwin/ChangeLog | 9 ++++ winsup/cygwin/fhandler_disk_file.cc | 83 +++++++++++++++++++---------- winsup/cygwin/path.h | 1 + 3 files changed, 64 insertions(+), 29 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 42da4a5e6..c9cdc2669 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,12 @@ +2003-09-11 Christopher Faylor + + * fhandler_disk_file.cc (path_conv::ndisk_links): Rename from + num_entries. Accept an argument and calculate any extra links needed + based on missing . and .. entries. + (fhandler_disk_file::fstat_helper): Always call pc->ndisks_links() to + calculate the number of links. + * path.h (path_conv::ndisk_links): Declare. + 2003-09-11 Christopher Faylor * path.cc (normalize_posix_path): Put check for '//' prefix back to diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index 5dbfa457b..7aba0b40c 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -29,36 +29,64 @@ details. */ #define _COMPILING_NEWLIB #include -static int __stdcall -num_entries (const char *win32_name) +unsigned __stdcall +path_conv::ndisk_links (DWORD nNumberOfLinks) { - WIN32_FIND_DATA buf; - HANDLE handle; - char buf1[MAX_PATH]; - int count = 0; + if (!isdir () || isremote ()) + return nNumberOfLinks; - strcpy (buf1, win32_name); - int len = strlen (buf1); - if (len == 0 || isdirsep (buf1[len - 1])) - strcat (buf1, "*"); - else - strcat (buf1, "/*"); /* */ + int len = strlen (*this); + char fn[len + 3]; + strcpy (fn, *this); - handle = FindFirstFileA (buf1, &buf); - - if (handle == INVALID_HANDLE_VALUE) - return 2; /* 2 is the minimum number of links to a dir, so... */ - int saw_dot = 2; - while (FindNextFileA (handle, &buf)) + const char *s; + unsigned count; + if (nNumberOfLinks <= 1) { - if (buf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - count++; - if (buf.cFileName[0] == '.' - && (buf.cFileName[1] == '\0' - || (buf.cFileName[1] == '.' && buf.cFileName[2] == '\0'))) - saw_dot--; + s = "/*"; + count = 0; } - FindClose (handle); + else + { + s = "/.."; + count = nNumberOfLinks; + } + + if (len == 0 || isdirsep (fn[len - 1])) + strcpy (fn, s + 1); + else + strcat (fn, s); + + WIN32_FIND_DATA buf; + HANDLE h = FindFirstFile (fn, &buf); + + int saw_dot = 2; + if (h != INVALID_HANDLE_VALUE) + { + if (nNumberOfLinks > 1) + saw_dot--; + else + while (FindNextFileA (h, &buf)) + { + if (buf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + count++; + if (buf.cFileName[0] == '.' + && (buf.cFileName[1] == '\0' + || (buf.cFileName[1] == '.' && buf.cFileName[2] == '\0'))) + saw_dot--; + } + FindClose (h); + } + + if (nNumberOfLinks > 1) + { + fn[len + 2] = '\0'; + h = FindFirstFile (fn, &buf); + if (h) + saw_dot--; + FindClose (h); + } + return count + saw_dot; } @@ -212,10 +240,7 @@ fhandler_disk_file::fstat_helper (struct __stat64 *buf, path_conv *pc, This is too slow on remote drives, so we do without it. Setting the count to 2 confuses `find (1)' command. So let's try it with `1' as link count. */ - if (pc->isdir () && !pc->isremote () && nNumberOfLinks == 1) - buf->st_nlink = num_entries (pc->get_win32 ()); - else - buf->st_nlink = nNumberOfLinks; + buf->st_nlink = pc->ndisk_links (nNumberOfLinks); /* Assume that if a drive has ACL support it MAY have valid "inodes". It definitely does not have valid inodes if it does not have ACL diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index f92e2d3dc..cd5656d80 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -164,6 +164,7 @@ class path_conv DWORD volser () { return fs.serial; } const char *volname () {return fs.name; } void fillin (HANDLE h); + unsigned __stdcall ndisk_links (DWORD); char *normalized_path; private: char path[MAX_PATH];