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
#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;
}
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