* fhandler.h (enum dirent_states): Remove dirent_saw_cygdrive,
dirent_saw_dev and dirent_saw_proc. (fhandler_cygdrive::open): Declare. (fhandler_cygdrive::close): Declare. * fhandler_disk_file.cc (class __DIR_mounts): Move to beginning of file. (__DIR_mounts::check_mount): New parameter to indicate if inode number is needed in calling function or not. Add /proc and /cygdrive handling. (__DIR_mounts::check_missing_mount): Ditto. (path_conv::ndisk_links): Use __DIR_mounts class to create correct hardlink count for directories with mount points in them. (fhandler_disk_file::readdir_helper): Remove /dev, /proc and /cygdrive handling. (fhandler_cygdrive::open): New method. (fhandler_cygdrive::close): New method. (fhandler_cygdrive::fstat): Always return fixed inode number 2 and fixed link count of 1. Drop call to set_drives. (fhandler_cygdrive::opendir): Drop call to get_namehash. (fhandler_cygdrive::readdir): Handle "." entry to return fixed inode number 2.
This commit is contained in:
parent
8d0f58ef37
commit
c115f31ff2
@ -1,3 +1,25 @@
|
||||
2006-03-01 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* fhandler.h (enum dirent_states): Remove dirent_saw_cygdrive,
|
||||
dirent_saw_dev and dirent_saw_proc.
|
||||
(fhandler_cygdrive::open): Declare.
|
||||
(fhandler_cygdrive::close): Declare.
|
||||
* fhandler_disk_file.cc (class __DIR_mounts): Move to beginning of file.
|
||||
(__DIR_mounts::check_mount): New parameter to indicate if inode number
|
||||
is needed in calling function or not. Add /proc and /cygdrive handling.
|
||||
(__DIR_mounts::check_missing_mount): Ditto.
|
||||
(path_conv::ndisk_links): Use __DIR_mounts class to create correct
|
||||
hardlink count for directories with mount points in them.
|
||||
(fhandler_disk_file::readdir_helper): Remove /dev, /proc and /cygdrive
|
||||
handling.
|
||||
(fhandler_cygdrive::open): New method.
|
||||
(fhandler_cygdrive::close): New method.
|
||||
(fhandler_cygdrive::fstat): Always return fixed inode number 2 and
|
||||
fixed link count of 1. Drop call to set_drives.
|
||||
(fhandler_cygdrive::opendir): Drop call to get_namehash.
|
||||
(fhandler_cygdrive::readdir): Handle "." entry to return fixed inode
|
||||
number 2.
|
||||
|
||||
2006-03-01 Christopher Faylor <cgf@timesys.com>
|
||||
|
||||
* cygwin.din: Fix some erroneous SIGFE/NOSIGFE settings.
|
||||
|
@ -45,11 +45,8 @@ enum dirent_states
|
||||
dirent_saw_dot_dot = 0x0002,
|
||||
dirent_saw_eof = 0x0004,
|
||||
dirent_isroot = 0x0008,
|
||||
dirent_saw_cygdrive = 0x0010,
|
||||
dirent_saw_dev = 0x0020,
|
||||
dirent_saw_proc = 0x0040,
|
||||
dirent_set_d_ino = 0x0080,
|
||||
dirent_get_d_ino = 0x0100
|
||||
dirent_set_d_ino = 0x0010,
|
||||
dirent_get_d_ino = 0x0020
|
||||
};
|
||||
|
||||
enum conn_state
|
||||
@ -697,6 +694,8 @@ class fhandler_cygdrive: public fhandler_disk_file
|
||||
void set_drives ();
|
||||
public:
|
||||
fhandler_cygdrive ();
|
||||
int open (int flags, mode_t mode);
|
||||
int close ();
|
||||
DIR *opendir ();
|
||||
int readdir (DIR *, dirent *) __attribute__ ((regparm (3)));
|
||||
void rewinddir (DIR *);
|
||||
|
@ -34,6 +34,97 @@ details. */
|
||||
#define _COMPILING_NEWLIB
|
||||
#include <dirent.h>
|
||||
|
||||
class __DIR_mounts
|
||||
{
|
||||
int count;
|
||||
const char *parent_dir;
|
||||
int parent_dir_len;
|
||||
char *mounts[MAX_MOUNTS];
|
||||
bool found[MAX_MOUNTS + 2];
|
||||
|
||||
#define __DIR_PROC (MAX_MOUNTS)
|
||||
#define __DIR_CYGDRIVE (MAX_MOUNTS+1)
|
||||
|
||||
__ino64_t eval_ino (int idx)
|
||||
{
|
||||
__ino64_t ino = 0;
|
||||
char fname[CYG_MAX_PATH];
|
||||
struct __stat64 st;
|
||||
int len = parent_dir_len;
|
||||
|
||||
strcpy (fname, parent_dir);
|
||||
if (fname[len - 1] != '/')
|
||||
fname[len++] = '/';
|
||||
strcpy (fname + len, mounts[idx]);
|
||||
if (!lstat64 (fname, &st))
|
||||
ino = st.st_ino;
|
||||
return ino;
|
||||
}
|
||||
|
||||
public:
|
||||
__DIR_mounts (const char *posix_path)
|
||||
: parent_dir (posix_path)
|
||||
{
|
||||
parent_dir_len = strlen (parent_dir);
|
||||
count = mount_table->get_mounts_here (parent_dir, parent_dir_len, mounts);
|
||||
rewind ();
|
||||
}
|
||||
__ino64_t check_mount (const char *name, __ino64_t ino, bool eval = true)
|
||||
{
|
||||
if (parent_dir_len == 1) /* root dir */
|
||||
{
|
||||
if (strcasematch (name, "proc"))
|
||||
{
|
||||
found[__DIR_PROC] = true;
|
||||
return hash_path_name (0, "/proc");
|
||||
}
|
||||
if (strlen (name) == mount_table->cygdrive_len - 2
|
||||
&& strncasematch (name, mount_table->cygdrive + 1,
|
||||
mount_table->cygdrive_len - 2))
|
||||
{
|
||||
found[__DIR_CYGDRIVE] = true;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < count; ++i)
|
||||
if (strcasematch (name, mounts[i]))
|
||||
{
|
||||
found[i] = true;
|
||||
return eval ? eval_ino (i) : 1;
|
||||
}
|
||||
return ino;
|
||||
}
|
||||
__ino64_t check_missing_mount (char *ret_name, bool eval = true)
|
||||
{
|
||||
for (int i = 0; i < count; ++i)
|
||||
if (!found[i])
|
||||
{
|
||||
found[i] = true;
|
||||
strcpy (ret_name, mounts[i]);
|
||||
return eval ? eval_ino (i) : 1;
|
||||
}
|
||||
if (parent_dir_len == 1) /* root dir */
|
||||
{
|
||||
if (!found[__DIR_PROC])
|
||||
{
|
||||
found[__DIR_PROC] = true;
|
||||
strcpy (ret_name, "proc");
|
||||
return hash_path_name (0, "/proc");
|
||||
}
|
||||
if (!found[__DIR_CYGDRIVE])
|
||||
{
|
||||
found[__DIR_CYGDRIVE] = true;
|
||||
strncpy (ret_name, mount_table->cygdrive + 1,
|
||||
mount_table->cygdrive_len - 2);
|
||||
ret_name[mount_table->cygdrive_len - 2] = '\0';
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void rewind () { memset (found, 0, sizeof found); }
|
||||
};
|
||||
|
||||
unsigned __stdcall
|
||||
path_conv::ndisk_links (DWORD nNumberOfLinks)
|
||||
{
|
||||
@ -46,6 +137,7 @@ path_conv::ndisk_links (DWORD nNumberOfLinks)
|
||||
|
||||
const char *s;
|
||||
unsigned count;
|
||||
__DIR_mounts *dir = new __DIR_mounts (normalized_path);
|
||||
if (nNumberOfLinks <= 1)
|
||||
{
|
||||
s = "/*";
|
||||
@ -79,6 +171,7 @@ path_conv::ndisk_links (DWORD nNumberOfLinks)
|
||||
&& (buf.cFileName[1] == '\0'
|
||||
|| (buf.cFileName[1] == '.' && buf.cFileName[2] == '\0')))
|
||||
saw_dot--;
|
||||
dir->check_mount (buf.cFileName, 0, false);
|
||||
}
|
||||
while (FindNextFileA (h, &buf));
|
||||
FindClose (h);
|
||||
@ -92,6 +185,10 @@ path_conv::ndisk_links (DWORD nNumberOfLinks)
|
||||
saw_dot--;
|
||||
FindClose (h);
|
||||
}
|
||||
while (dir->check_missing_mount (buf.cFileName, false))
|
||||
++count;
|
||||
|
||||
delete dir;
|
||||
|
||||
return count + saw_dot;
|
||||
}
|
||||
@ -1403,62 +1500,6 @@ struct __DIR_cache
|
||||
#define d_cachepos(d) (((__DIR_cache *) (d)->__d_dirname)->__pos)
|
||||
#define d_cache(d) (((__DIR_cache *) (d)->__d_dirname)->__cache)
|
||||
|
||||
class __DIR_mounts
|
||||
{
|
||||
int count;
|
||||
const char *parent_dir;
|
||||
int parent_dir_len;
|
||||
char *mounts[MAX_MOUNTS];
|
||||
bool found[MAX_MOUNTS];
|
||||
|
||||
__ino64_t eval_ino (int idx)
|
||||
{
|
||||
__ino64_t ino = 0;
|
||||
char fname[CYG_MAX_PATH];
|
||||
struct __stat64 st;
|
||||
int len = parent_dir_len;
|
||||
|
||||
strcpy (fname, parent_dir);
|
||||
if (fname[len - 1] != '/')
|
||||
fname[len++] = '/';
|
||||
strcpy (fname + len, mounts[idx]);
|
||||
if (!lstat64 (fname, &st))
|
||||
ino = st.st_ino;
|
||||
return ino;
|
||||
}
|
||||
|
||||
public:
|
||||
__DIR_mounts (const char *posix_path)
|
||||
: parent_dir (posix_path)
|
||||
{
|
||||
parent_dir_len = strlen (parent_dir);
|
||||
count = mount_table->get_mounts_here (parent_dir, parent_dir_len, mounts);
|
||||
rewind ();
|
||||
}
|
||||
__ino64_t check_mount (const char *name, __ino64_t ino)
|
||||
{
|
||||
for (int i = 0; i < count; ++i)
|
||||
if (strcasematch (name, mounts[i]))
|
||||
{
|
||||
found[i] = true;
|
||||
return eval_ino (i);
|
||||
}
|
||||
return ino;
|
||||
}
|
||||
__ino64_t check_missing_mount (char *ret_name)
|
||||
{
|
||||
for (int i = 0; i < count; ++i)
|
||||
if (!found[i])
|
||||
{
|
||||
found[i] = true;
|
||||
strcpy (ret_name, mounts[i]);
|
||||
return eval_ino (i);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void rewind () { memset (found, 0, sizeof found); }
|
||||
};
|
||||
|
||||
#define d_mounts(d) ((__DIR_mounts *) (d)->__d_internal)
|
||||
|
||||
DIR *
|
||||
@ -1582,26 +1623,6 @@ fhandler_disk_file::readdir_helper (DIR *dir, dirent *de, DWORD w32_err,
|
||||
bool added = false;
|
||||
if ((de->d_ino = d_mounts (dir)->check_missing_mount (fname)))
|
||||
added = true;
|
||||
else if (!(dir->__flags & dirent_isroot))
|
||||
/* nothing */;
|
||||
else if (0 && !(dir->__flags & dirent_saw_dev))
|
||||
{
|
||||
strcpy (fname, "dev");
|
||||
added = true;
|
||||
}
|
||||
else if (!(dir->__flags & dirent_saw_proc))
|
||||
{
|
||||
strcpy (fname, "proc");
|
||||
added = true;
|
||||
}
|
||||
else if (!(dir->__flags & dirent_saw_cygdrive)
|
||||
&& mount_table->cygdrive_len > 1)
|
||||
{
|
||||
strcpy (fname, mount_table->cygdrive + 1);
|
||||
fname[mount_table->cygdrive_len - 2] = '\0';
|
||||
added = true;
|
||||
}
|
||||
|
||||
if (!added)
|
||||
return geterrno_from_win_error (w32_err);
|
||||
|
||||
@ -1630,32 +1651,6 @@ fhandler_disk_file::readdir_helper (DIR *dir, dirent *de, DWORD w32_err,
|
||||
fnunmunge (de->d_name, fname);
|
||||
else
|
||||
strcpy (de->d_name, fname);
|
||||
if (dir->__flags & dirent_isroot)
|
||||
{
|
||||
if (strcasematch (de->d_name, "dev"))
|
||||
{
|
||||
dir->__flags |= dirent_saw_dev;
|
||||
/* In contrast to /proc, /dev has no own fhandler which cares
|
||||
for inode numbers. So, if the directory exists physically,
|
||||
its "real" inode number should be used. Otherwise it must
|
||||
not be faked until we add a /dev fhandler to Cygwin. */
|
||||
#if 0
|
||||
de->d_ino = hash_path_name (0, "/dev");
|
||||
#endif
|
||||
}
|
||||
else if (strcasematch (de->d_name, "proc"))
|
||||
{
|
||||
dir->__flags |= dirent_saw_proc;
|
||||
de->d_ino = hash_path_name (0, "/proc");
|
||||
}
|
||||
if (strlen (de->d_name) == mount_table->cygdrive_len - 2
|
||||
&& strncasematch (de->d_name, mount_table->cygdrive + 1,
|
||||
mount_table->cygdrive_len - 2))
|
||||
{
|
||||
dir->__flags |= dirent_saw_cygdrive;
|
||||
de->d_ino = 0;
|
||||
}
|
||||
}
|
||||
if (dir->__d_position == 0 && !strcmp (fname, "."))
|
||||
dir->__flags |= dirent_saw_dot;
|
||||
else if (dir->__d_position == 1 && !strcmp (fname, ".."))
|
||||
@ -1931,6 +1926,31 @@ fhandler_cygdrive::fhandler_cygdrive () :
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
fhandler_cygdrive::open (int flags, mode_t mode)
|
||||
{
|
||||
if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
|
||||
{
|
||||
set_errno (EEXIST);
|
||||
return 0;
|
||||
}
|
||||
if (flags & O_WRONLY)
|
||||
{
|
||||
set_errno (EISDIR);
|
||||
return 0;
|
||||
}
|
||||
flags |= O_DIROPEN;
|
||||
set_flags (flags);
|
||||
nohandle (true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
fhandler_cygdrive::close ()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define DRVSZ sizeof ("x:\\")
|
||||
void
|
||||
fhandler_cygdrive::set_drives ()
|
||||
@ -1945,12 +1965,8 @@ int
|
||||
fhandler_cygdrive::fstat (struct __stat64 *buf)
|
||||
{
|
||||
buf->st_mode = S_IFDIR | 0555;
|
||||
/* Call get_namehash before calling set_drives, otherwise the namehash
|
||||
is broken due to overwriting the win32 path in set_drives. */
|
||||
buf->st_ino = get_namehash ();
|
||||
if (!ndrives)
|
||||
set_drives ();
|
||||
buf->st_nlink = ndrives + 2;
|
||||
buf->st_ino = 2;
|
||||
buf->st_nlink = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1960,9 +1976,6 @@ fhandler_cygdrive::opendir ()
|
||||
DIR *dir;
|
||||
|
||||
dir = fhandler_disk_file::opendir ();
|
||||
/* Call get_namehash before calling set_drives, otherwise the namehash
|
||||
is broken due to overwriting the win32 path in set_drives. */
|
||||
get_namehash ();
|
||||
if (dir && !ndrives)
|
||||
set_drives ();
|
||||
|
||||
@ -1975,7 +1988,15 @@ fhandler_cygdrive::readdir (DIR *dir, dirent *de)
|
||||
while (true)
|
||||
{
|
||||
if (!pdrive || !*pdrive)
|
||||
return ENMFILE;
|
||||
{
|
||||
if (!(dir->__flags & dirent_saw_dot))
|
||||
{
|
||||
de->d_name[0] = '.';
|
||||
de->d_name[1] = '\0';
|
||||
de->d_ino = 2;
|
||||
}
|
||||
return ENMFILE;
|
||||
}
|
||||
if (GetFileAttributes (pdrive) != INVALID_FILE_ATTRIBUTES)
|
||||
break;
|
||||
pdrive = strchr (pdrive, '\0') + 1;
|
||||
|
Loading…
Reference in New Issue
Block a user