summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2003-09-11 23:30:26 +0000
committerChristopher Faylor <me@cgf.cx>2003-09-11 23:30:26 +0000
commit9e24b8ace9ef4865df9e1f2f23313be45abeca21 (patch)
treeb7005ab92fc07ed061e5f50637577e0ad4648459
parentce044d8fe026989fdc02f5a30a1cf2b7e6a36d85 (diff)
downloadcygnal-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.
-rw-r--r--winsup/cygwin/ChangeLog9
-rw-r--r--winsup/cygwin/fhandler_disk_file.cc75
-rw-r--r--winsup/cygwin/path.h1
3 files changed, 60 insertions, 25 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 42da4a5e6..c9cdc2669 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,14 @@
2003-09-11 Christopher Faylor <cgf@redhat.com>
+ * 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 <cgf@redhat.com>
+
* path.cc (normalize_posix_path): Put check for '//' prefix back to
denote a UNC path.
(slash_unc_prefix_p): Remove vestige of old //c method for accessing
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
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];