* 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.
This commit is contained in:
Christopher Faylor 2003-09-11 23:30:26 +00:00
parent ce044d8fe0
commit 9e24b8ace9
3 changed files with 64 additions and 29 deletions

View File

@ -1,3 +1,12 @@
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

View File

@ -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;
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

View File

@ -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];