* path.cc (conv_path_list): Fix wild indexing into path due to conflicting
methods for setting src pointer. * dir.cc (opendir): Only pass path_conv argument to opendir, since name is already part of the fhandler. * dtable.cc (dtable::build_fhandler): Accomodate new FH_CYGDRIVE type. * fhandler.cc (fhandler_base::opendir): Nuke name argument. * fhandler.h: Add FH_CYGDRIVE to "device" enum. (fhandler_base::opendir): Nuke name argument. (fhandler_disk_file::opendir): Ditto. (fhandler_disk_file::fhandler_disk_file): Declare new method which passes devtype through. (fhandler_cygdrive): Add elements for tracking drives. (fhandler_cygdrive::set_drives): Declare new method. (fhandler_cygdrive::iscygdrive_root): Declare new method. (fhandler_cygdrive::opendir): Declare new method. (fhandler_cygdrive::readdir): Declare new method. (fhandler_cygdrive::telldir): Declare new method. (fhandler_cygdrive::seekdir): Declare new method. (fhandler_cygdrive::rewinddir): Declare new method. (fhandler_cygdrive::closedir): Declare new method. (fhandler_cygdrive::fstat): Declare new method. * fhandler_disk_file.cc (fhandler_disk_file::fhandler_disk_file): Define new method which passes devtype through. (fhandler_disk_file::open): Tweak debug output. (fhandler_disk_file::opendir): Nuke first argument. Use info from path_conv and class rather than calling fstat. (fhandler_cygdrive::set_drives): New method. (fhandler_cygdrive::iscygdrive_root): New method. (fhandler_cygdrive::opendir): New method. (fhandler_cygdrive::readdir): New method. (fhandler_cygdrive::telldir): New method. (fhandler_cygdrive::seekdir): New method. (fhandler_cygdrive::rewinddir): New method. (fhandler_cygdrive::closedir): New method. (fhandler_cygdrive::fstat): New method. * path.cc (iscygdrive_device): Assume cygdriveness is already verified. (path_conv::check): Treat FH_CYGDRIVE "method" as a special case, setting file attributes as needed. (mount_info::conv_to_win32_path): Allow stand-alone /cygdrive, meaning "the directory which contains all of the drives on the system". (fillout_mntent): Use cyg_tolower for conversions. (mount_info::cygdrive_win32_path): Replace unused argument with unit number. * shared_info.h (mount_info::cygdrive_win32_path): Reflect argument change.
This commit is contained in:
@ -338,8 +338,13 @@ fhandler_disk_file::fstat_helper (struct stat *buf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
fhandler_disk_file::fhandler_disk_file (DWORD devtype) :
|
||||
fhandler_base (devtype)
|
||||
{
|
||||
}
|
||||
|
||||
fhandler_disk_file::fhandler_disk_file () :
|
||||
fhandler_base (FH_DISK)
|
||||
fhandler_base (FH_DISK)
|
||||
{
|
||||
}
|
||||
|
||||
@ -348,7 +353,7 @@ fhandler_disk_file::open (path_conv *real_path, int flags, mode_t mode)
|
||||
{
|
||||
if (real_path->case_clash && flags & O_CREAT)
|
||||
{
|
||||
debug_printf ("Caseclash detected.");
|
||||
debug_printf ("case clash detected");
|
||||
set_errno (ECASECLASH);
|
||||
return 0;
|
||||
}
|
||||
@ -564,14 +569,13 @@ fhandler_disk_file::lock (int cmd, struct flock *fl)
|
||||
}
|
||||
|
||||
DIR *
|
||||
fhandler_disk_file::opendir (const char *name, path_conv& real_name)
|
||||
fhandler_disk_file::opendir (path_conv& real_name)
|
||||
{
|
||||
struct stat statbuf;
|
||||
DIR *dir;
|
||||
DIR *res = NULL;
|
||||
size_t len;
|
||||
|
||||
if (fstat (&statbuf, &real_name) ||!(statbuf.st_mode & S_IFDIR))
|
||||
if (!real_name.isdir ())
|
||||
set_errno (ENOTDIR);
|
||||
else if ((len = strlen (real_name))> MAX_PATH - 3)
|
||||
set_errno (ENAMETOOLONG);
|
||||
@ -606,12 +610,12 @@ fhandler_disk_file::opendir (const char *name, path_conv& real_name)
|
||||
dir->__d_cookie = __DIRENT_COOKIE;
|
||||
dir->__d_u.__d_data.__handle = INVALID_HANDLE_VALUE;
|
||||
dir->__d_position = 0;
|
||||
dir->__d_dirhash = statbuf.st_ino;
|
||||
dir->__d_dirhash = get_namehash ();
|
||||
|
||||
res = dir;
|
||||
}
|
||||
|
||||
syscall_printf ("%p = opendir (%s)", res, name);
|
||||
syscall_printf ("%p = opendir (%s)", res, get_name ());
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -702,7 +706,7 @@ fhandler_disk_file::readdir (DIR *dir)
|
||||
dir->__d_dirent->d_ino = hash_path_name (dino, buf.cFileName);
|
||||
}
|
||||
|
||||
++dir->__d_position;
|
||||
dir->__d_position++;
|
||||
res = dir->__d_dirent;
|
||||
syscall_printf ("%p = readdir (%p) (%s)",
|
||||
&dir->__d_dirent, dir, buf.cFileName);
|
||||
@ -720,7 +724,7 @@ fhandler_disk_file::seekdir (DIR *dir, off_t loc)
|
||||
{
|
||||
rewinddir (dir);
|
||||
while (loc > dir->__d_position)
|
||||
if (! readdir (dir))
|
||||
if (!readdir (dir))
|
||||
break;
|
||||
}
|
||||
|
||||
@ -748,3 +752,100 @@ fhandler_disk_file::closedir (DIR *dir)
|
||||
syscall_printf ("%d = closedir (%p)", res, dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fhandler_cygdrive::fhandler_cygdrive (int unit) :
|
||||
fhandler_disk_file (FH_CYGDRIVE), unit (unit), ndrives (0), pdrive (NULL)
|
||||
{
|
||||
}
|
||||
|
||||
#define DRVSZ sizeof ("x:\\")
|
||||
void
|
||||
fhandler_cygdrive::set_drives ()
|
||||
{
|
||||
const int len = 1 + 26 * DRVSZ;
|
||||
win32_path_name = (char *) crealloc (win32_path_name, len);
|
||||
|
||||
ndrives = GetLogicalDriveStrings (len, win32_path_name) / DRVSZ;
|
||||
pdrive = win32_path_name;
|
||||
}
|
||||
|
||||
int
|
||||
fhandler_cygdrive::fstat (struct stat *buf, path_conv *pc)
|
||||
{
|
||||
if (!iscygdrive_root ())
|
||||
return fhandler_disk_file::fstat (buf, pc);
|
||||
buf->st_mode = S_IFDIR | 0555;
|
||||
if (!ndrives)
|
||||
set_drives ();
|
||||
buf->st_nlink = ndrives;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DIR *
|
||||
fhandler_cygdrive::opendir (path_conv& real_name)
|
||||
{
|
||||
DIR *dir;
|
||||
|
||||
dir = fhandler_disk_file::opendir (real_name);
|
||||
if (dir && iscygdrive_root () && !ndrives)
|
||||
set_drives ();
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
struct dirent *
|
||||
fhandler_cygdrive::readdir (DIR *dir)
|
||||
{
|
||||
if (!iscygdrive_root ())
|
||||
return fhandler_disk_file::readdir (dir);
|
||||
if (!pdrive || !*pdrive)
|
||||
{
|
||||
set_errno (ENMFILE);
|
||||
return NULL;
|
||||
}
|
||||
*dir->__d_dirent->d_name = cyg_tolower (*pdrive);
|
||||
dir->__d_dirent->d_name[1] = '\0';
|
||||
dir->__d_position++;
|
||||
pdrive += DRVSZ;
|
||||
syscall_printf ("%p = readdir (%p) (%s)", &dir->__d_dirent, dir,
|
||||
dir->__d_dirent->d_name);
|
||||
return dir->__d_dirent;
|
||||
}
|
||||
|
||||
off_t
|
||||
fhandler_cygdrive::telldir (DIR *dir)
|
||||
{
|
||||
return fhandler_disk_file::telldir (dir);
|
||||
}
|
||||
|
||||
void
|
||||
fhandler_cygdrive::seekdir (DIR *dir, off_t loc)
|
||||
{
|
||||
if (!iscygdrive_root ())
|
||||
return fhandler_disk_file::seekdir (dir, loc);
|
||||
|
||||
for (pdrive = win32_path_name, dir->__d_position = -1; *pdrive; pdrive += DRVSZ)
|
||||
if (++dir->__d_position >= loc)
|
||||
break;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
fhandler_cygdrive::rewinddir (DIR *dir)
|
||||
{
|
||||
if (!iscygdrive_root ())
|
||||
return fhandler_disk_file::rewinddir (dir);
|
||||
pdrive = win32_path_name;
|
||||
dir->__d_position = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
fhandler_cygdrive::closedir (DIR *dir)
|
||||
{
|
||||
if (!iscygdrive_root ())
|
||||
return fhandler_disk_file::closedir (dir);
|
||||
pdrive = win32_path_name;
|
||||
return -1;
|
||||
}
|
||||
|
Reference in New Issue
Block a user