diff options
author | Christopher Faylor <me@cgf.cx> | 2003-09-11 23:30:26 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2003-09-11 23:30:26 +0000 |
commit | 9e24b8ace9ef4865df9e1f2f23313be45abeca21 (patch) | |
tree | b7005ab92fc07ed061e5f50637577e0ad4648459 /winsup/cygwin/fhandler_disk_file.cc | |
parent | ce044d8fe026989fdc02f5a30a1cf2b7e6a36d85 (diff) | |
download | cygnal-9e24b8ace9ef4865df9e1f2f23313be45abeca21.tar.gz cygnal-9e24b8ace9ef4865df9e1f2f23313be45abeca21.tar.bz2 cygnal-9e24b8ace9ef4865df9e1f2f23313be45abeca21.zip |
* 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.
Diffstat (limited to 'winsup/cygwin/fhandler_disk_file.cc')
-rw-r--r-- | winsup/cygwin/fhandler_disk_file.cc | 75 |
1 files changed, 50 insertions, 25 deletions
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 <dirent.h> -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; + + int len = strlen (*this); + char fn[len + 3]; + strcpy (fn, *this); + + const char *s; + unsigned count; + if (nNumberOfLinks <= 1) + { + s = "/*"; + count = 0; + } + else + { + s = "/.."; + count = nNumberOfLinks; + } - strcpy (buf1, win32_name); - int len = strlen (buf1); - if (len == 0 || isdirsep (buf1[len - 1])) - strcat (buf1, "*"); + if (len == 0 || isdirsep (fn[len - 1])) + strcpy (fn, s + 1); else - strcat (buf1, "/*"); /* */ + strcat (fn, s); - handle = FindFirstFileA (buf1, &buf); + WIN32_FIND_DATA buf; + HANDLE h = FindFirstFile (fn, &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)) + if (h != INVALID_HANDLE_VALUE) { - if (buf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - count++; - if (buf.cFileName[0] == '.' - && (buf.cFileName[1] == '\0' - || (buf.cFileName[1] == '.' && buf.cFileName[2] == '\0'))) + 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); } - FindClose (handle); + 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 |