* include/sys/dirent.h (struct __DIR): Rename __d_unused to
__d_internal. * fhandler_disk_file.cc (struct __DIR_cache): Remove useless "typedef". (d_dirname): Remove useless "struct". (d_cachepos): Ditto. (d_cache): Ditto. (class __DIR_mounts): New class, implementing mount point tracking for readdir. (d_mounts): New macro for easy access to __DIR_mounts structure. (fhandler_disk_file::opendir): Allocate __DIR_mounts structure and let __d_internal element of dir point to it. (fhandler_disk_file::readdir_helper): Add mount points in the current directory, which don't have a real directory backing them. Don't generate an inode number for /dev. Add comment, why. (fhandler_disk_file::readdir): Move filling fname to an earlier point. Check if current entry is a mount point and evaluate correct inode number for it. (fhandler_disk_file::readdir_9x): Ditto. (fhandler_disk_file::rewinddir): Set all mount points in this directory to "not found" so that they are listed again after calling rewinddir(). (fhandler_disk_file::closedir): Deallocate __DIR_mounts structure. * path.cc (mount_info::get_mounts_here): New method to evaluate a list of mount points in a given parent directory. * shared_info.h (class mount_info): Declare get_mounts_here.
This commit is contained in:
parent
0e3befd678
commit
e817fd3c8b
|
@ -1,3 +1,30 @@
|
||||||
|
2006-03-01 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* include/sys/dirent.h (struct __DIR): Rename __d_unused to
|
||||||
|
__d_internal.
|
||||||
|
* fhandler_disk_file.cc (struct __DIR_cache): Remove useless "typedef".
|
||||||
|
(d_dirname): Remove useless "struct".
|
||||||
|
(d_cachepos): Ditto.
|
||||||
|
(d_cache): Ditto.
|
||||||
|
(class __DIR_mounts): New class, implementing mount point tracking
|
||||||
|
for readdir.
|
||||||
|
(d_mounts): New macro for easy access to __DIR_mounts structure.
|
||||||
|
(fhandler_disk_file::opendir): Allocate __DIR_mounts structure and
|
||||||
|
let __d_internal element of dir point to it.
|
||||||
|
(fhandler_disk_file::readdir_helper): Add mount points in the current
|
||||||
|
directory, which don't have a real directory backing them.
|
||||||
|
Don't generate an inode number for /dev. Add comment, why.
|
||||||
|
(fhandler_disk_file::readdir): Move filling fname to an earlier point.
|
||||||
|
Check if current entry is a mount point and evaluate correct inode
|
||||||
|
number for it.
|
||||||
|
(fhandler_disk_file::readdir_9x): Ditto.
|
||||||
|
(fhandler_disk_file::rewinddir): Set all mount points in this directory
|
||||||
|
to "not found" so that they are listed again after calling rewinddir().
|
||||||
|
(fhandler_disk_file::closedir): Deallocate __DIR_mounts structure.
|
||||||
|
* path.cc (mount_info::get_mounts_here): New method to evaluate a list
|
||||||
|
of mount points in a given parent directory.
|
||||||
|
* shared_info.h (class mount_info): Declare get_mounts_here.
|
||||||
|
|
||||||
2006-02-28 Corinna Vinschen <corinna@vinschen.de>
|
2006-02-28 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* fhandler_disk_file.cc (fhandler_disk_file::opendir): Use iscygdrive
|
* fhandler_disk_file.cc (fhandler_disk_file::opendir): Use iscygdrive
|
||||||
|
|
|
@ -1392,16 +1392,74 @@ fhandler_disk_file::rmdir ()
|
||||||
* (sizeof (FILE_ID_BOTH_DIR_INFORMATION) \
|
* (sizeof (FILE_ID_BOTH_DIR_INFORMATION) \
|
||||||
+ 2 * CYG_MAX_PATH))
|
+ 2 * CYG_MAX_PATH))
|
||||||
|
|
||||||
typedef struct __DIR_cache
|
struct __DIR_cache
|
||||||
{
|
{
|
||||||
char __name[CYG_MAX_PATH];
|
char __name[CYG_MAX_PATH];
|
||||||
ULONG __pos;
|
ULONG __pos;
|
||||||
char __cache[DIR_BUF_SIZE];
|
char __cache[DIR_BUF_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define d_dirname(d) (((struct __DIR_cache *) (d)->__d_dirname)->__name)
|
#define d_dirname(d) (((__DIR_cache *) (d)->__d_dirname)->__name)
|
||||||
#define d_cachepos(d) (((struct __DIR_cache *) (d)->__d_dirname)->__pos)
|
#define d_cachepos(d) (((__DIR_cache *) (d)->__d_dirname)->__pos)
|
||||||
#define d_cache(d) (((struct __DIR_cache *) (d)->__d_dirname)->__cache)
|
#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 *
|
DIR *
|
||||||
fhandler_disk_file::opendir ()
|
fhandler_disk_file::opendir ()
|
||||||
|
@ -1458,6 +1516,7 @@ fhandler_disk_file::opendir ()
|
||||||
dir->__d_position = 0;
|
dir->__d_position = 0;
|
||||||
|
|
||||||
dir->__flags = (pc.normalized_path[0] == '/' && pc.normalized_path[1] == '\0') ? dirent_isroot : 0;
|
dir->__flags = (pc.normalized_path[0] == '/' && pc.normalized_path[1] == '\0') ? dirent_isroot : 0;
|
||||||
|
dir->__d_internal = (unsigned) new __DIR_mounts (pc.normalized_path);
|
||||||
if (wincap.is_winnt ())
|
if (wincap.is_winnt ())
|
||||||
{
|
{
|
||||||
d_cachepos (dir) = 0;
|
d_cachepos (dir) = 0;
|
||||||
|
@ -1521,7 +1580,9 @@ fhandler_disk_file::readdir_helper (DIR *dir, dirent *de, DWORD w32_err,
|
||||||
if (w32_err)
|
if (w32_err)
|
||||||
{
|
{
|
||||||
bool added = false;
|
bool added = false;
|
||||||
if (!(dir->__flags & dirent_isroot))
|
if ((de->d_ino = d_mounts (dir)->check_missing_mount (fname)))
|
||||||
|
added = true;
|
||||||
|
else if (!(dir->__flags & dirent_isroot))
|
||||||
/* nothing */;
|
/* nothing */;
|
||||||
else if (0 && !(dir->__flags & dirent_saw_dev))
|
else if (0 && !(dir->__flags & dirent_saw_dev))
|
||||||
{
|
{
|
||||||
|
@ -1574,7 +1635,13 @@ fhandler_disk_file::readdir_helper (DIR *dir, dirent *de, DWORD w32_err,
|
||||||
if (strcasematch (de->d_name, "dev"))
|
if (strcasematch (de->d_name, "dev"))
|
||||||
{
|
{
|
||||||
dir->__flags |= dirent_saw_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");
|
de->d_ino = hash_path_name (0, "/dev");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else if (strcasematch (de->d_name, "proc"))
|
else if (strcasematch (de->d_name, "proc"))
|
||||||
{
|
{
|
||||||
|
@ -1697,7 +1764,9 @@ fhandler_disk_file::readdir (DIR *dir, dirent *de)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
FileName = ((PFILE_BOTH_DIR_INFORMATION) buf)->FileName;
|
FileName = ((PFILE_BOTH_DIR_INFORMATION) buf)->FileName;
|
||||||
|
sys_wcstombs (fname, CYG_MAX_PATH - 1, FileName, buf->FileNameLength / 2);
|
||||||
|
|
||||||
|
de->d_ino = d_mounts (dir)->check_mount (fname, de->d_ino);
|
||||||
if (de->d_ino == 0 && (dir->__flags & dirent_set_d_ino))
|
if (de->d_ino == 0 && (dir->__flags & dirent_set_d_ino))
|
||||||
{
|
{
|
||||||
OBJECT_ATTRIBUTES attr;
|
OBJECT_ATTRIBUTES attr;
|
||||||
|
@ -1723,7 +1792,6 @@ fhandler_disk_file::readdir (DIR *dir, dirent *de)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sys_wcstombs (fname, CYG_MAX_PATH - 1, FileName, buf->FileNameLength / 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(res = readdir_helper (dir, de, RtlNtStatusToDosError (status),
|
if (!(res = readdir_helper (dir, de, RtlNtStatusToDosError (status),
|
||||||
|
@ -1783,7 +1851,8 @@ fhandler_disk_file::readdir_9x (DIR *dir, dirent *de)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!lasterr)
|
||||||
|
de->d_ino = d_mounts (dir)->check_mount (buf.cFileName, de->d_ino);
|
||||||
if (!(res = readdir_helper (dir, de, lasterr, buf.dwFileAttributes,
|
if (!(res = readdir_helper (dir, de, lasterr, buf.dwFileAttributes,
|
||||||
buf.cFileName)))
|
buf.cFileName)))
|
||||||
dir->__d_position++;
|
dir->__d_position++;
|
||||||
|
@ -1825,12 +1894,14 @@ fhandler_disk_file::rewinddir (DIR *dir)
|
||||||
dir->__handle = INVALID_HANDLE_VALUE;
|
dir->__handle = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
dir->__d_position = 0;
|
dir->__d_position = 0;
|
||||||
|
d_mounts (dir)->rewind ();
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_disk_file::closedir (DIR *dir)
|
fhandler_disk_file::closedir (DIR *dir)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
delete d_mounts (dir);
|
||||||
if (!dir->__handle)
|
if (!dir->__handle)
|
||||||
/* ignore */;
|
/* ignore */;
|
||||||
else if (dir->__handle == INVALID_HANDLE_VALUE)
|
else if (dir->__handle == INVALID_HANDLE_VALUE)
|
||||||
|
|
|
@ -48,7 +48,7 @@ typedef struct __DIR
|
||||||
char *__d_dirname; /* directory name with trailing '*' */
|
char *__d_dirname; /* directory name with trailing '*' */
|
||||||
_off_t __d_position; /* used by telldir/seekdir */
|
_off_t __d_position; /* used by telldir/seekdir */
|
||||||
int __d_fd;
|
int __d_fd;
|
||||||
unsigned __d_unused;
|
unsigned __d_internal;
|
||||||
void *__handle;
|
void *__handle;
|
||||||
void *__fh;
|
void *__fh;
|
||||||
unsigned __flags;
|
unsigned __flags;
|
||||||
|
|
|
@ -1718,6 +1718,30 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
mount_info::get_mounts_here (const char *parent_dir, int parent_dir_len,
|
||||||
|
char **mount_points)
|
||||||
|
{
|
||||||
|
int n_mounts = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < nmounts; i++)
|
||||||
|
{
|
||||||
|
mount_item *mi = mount + posix_sorted[i];
|
||||||
|
char *last_slash = strrchr (mi->posix_path, '/');
|
||||||
|
if (!last_slash)
|
||||||
|
continue;
|
||||||
|
if (last_slash == mi->posix_path)
|
||||||
|
{
|
||||||
|
if (parent_dir_len == 1 && mi->posix_pathlen > 1)
|
||||||
|
mount_points[n_mounts++] = last_slash + 1;
|
||||||
|
}
|
||||||
|
else if (parent_dir_len == last_slash - mi->posix_path
|
||||||
|
&& strncasematch (parent_dir, mi->posix_path, parent_dir_len))
|
||||||
|
mount_points[n_mounts++] = last_slash + 1;
|
||||||
|
}
|
||||||
|
return n_mounts;
|
||||||
|
}
|
||||||
|
|
||||||
/* cygdrive_posix_path: Build POSIX path used as the
|
/* cygdrive_posix_path: Build POSIX path used as the
|
||||||
mount point for cygdrives created when there is no other way to
|
mount point for cygdrives created when there is no other way to
|
||||||
obtain a POSIX path from a Win32 one. */
|
obtain a POSIX path from a Win32 one. */
|
||||||
|
|
|
@ -91,6 +91,7 @@ class mount_info
|
||||||
int get_cygdrive_info (char *user, char *system, char* user_flags,
|
int get_cygdrive_info (char *user, char *system, char* user_flags,
|
||||||
char* system_flags);
|
char* system_flags);
|
||||||
void cygdrive_posix_path (const char *src, char *dst, int trailing_slash_p);
|
void cygdrive_posix_path (const char *src, char *dst, int trailing_slash_p);
|
||||||
|
int get_mounts_here (const char *parent_dir, int, char **mount_points);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue