diff options
author | Christopher Faylor <me@cgf.cx> | 2001-11-22 05:59:07 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2001-11-22 05:59:07 +0000 |
commit | 97a2e0756d28fc4d0cf62ce5778b7d73160f77e5 (patch) | |
tree | 8a0784e438d6d9528eeddb2397c027fc4685ec59 /winsup/cygwin/fhandler_disk_file.cc | |
parent | 53e61a867b154ddbf7a468dd94616ebc081dbd8f (diff) | |
download | cygnal-97a2e0756d28fc4d0cf62ce5778b7d73160f77e5.tar.gz cygnal-97a2e0756d28fc4d0cf62ce5778b7d73160f77e5.tar.bz2 cygnal-97a2e0756d28fc4d0cf62ce5778b7d73160f77e5.zip |
* 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.
Diffstat (limited to 'winsup/cygwin/fhandler_disk_file.cc')
-rw-r--r-- | winsup/cygwin/fhandler_disk_file.cc | 119 |
1 files changed, 110 insertions, 9 deletions
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index 888df2233..0585555c4 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -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; +} |