diff options
author | Christopher Faylor <me@cgf.cx> | 2001-10-01 04:10:07 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2001-10-01 04:10:07 +0000 |
commit | 47063f00e4eae2ed37096eda54429c025c0bc7b5 (patch) | |
tree | ecefbae309e397c0c4965abfb94ad2da05caeeee /winsup/cygwin/fhandler.cc | |
parent | c25c4c5ffcc8749993cc786b8a559f9d2e0e4684 (diff) | |
download | cygnal-47063f00e4eae2ed37096eda54429c025c0bc7b5.tar.gz cygnal-47063f00e4eae2ed37096eda54429c025c0bc7b5.tar.bz2 cygnal-47063f00e4eae2ed37096eda54429c025c0bc7b5.zip |
Add "path.h" include throughout, where needed. Use new path_conv methods and
operators to simplify testing for directory and attributes, throughout.
* path.h (path_conv::exists): New method.
(path_conv::has_attribute): Ditto.
(path_conv::isdir): Ditto.
(path_conv::DWORD &): New operator.
(path_conv::int &): Ditto.
* dir.cc (rmdir): Eliminate a goto.
* dtable.cc (dtable::build_fhandler): Accept opt and suffix info for
path_conv.check. Return fh == NULL on path_conv error. Pass unit to set_name
as appropriate.
(dtable::reset_unix_path_name): New method.
* dtable.h (dtable): Declare new method. Reflect arg changes to
build_fhandler.
* fhandler.cc (fhandler_disk_dummy_name): Eliminate.
(fhandler_base::set_name): Expect paths to be NULL. Build unix_path_name from
win32_path_name when it is a device.
(fhandler_base::reset_unix_path_name): New method.
(fhandler_base::raw_read): Report EISDIR when ERROR_INVALID_FUNCTION or
ERROR_INVALID_PARAMETER and reading a directory.
(fhandler_disk_file::fstat): Don't call stat_dev since we should now never be
calling fhandler_disk_file methods with devices.
(fhandler_base::fhandler_base): Clear {unix,win32}_path_name.
(fhandler_base::~fhandler_base): Always free {unix,win32}_path_name.
(fhandler_disk_file::fhandler_disk_file): Remove set_no_free_names kludge.
(fhandler_disk_file::open): Ditto.
* fhandler.h (fhandler_base::no_free_names): Eliminate.
(fhandler_base::set_no_free_names): Ditto.
* fhandler_tty.cc (fhandler_tty_slave::fhandler_tty_slave): Don't set
unix_path_name here.
* path.cc (fchdir): Lock fd table throughout. Use new
dtable::reset_unix_path_name method to reset path.
* syscalls.cc (stat_worker): Reorganize to always call fstat method. Pass
path_conv method to fhandler_*::open.
(chroot): Elminate a goto.
Diffstat (limited to 'winsup/cygwin/fhandler.cc')
-rw-r--r-- | winsup/cygwin/fhandler.cc | 126 |
1 files changed, 54 insertions, 72 deletions
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index a670e7860..54adc8dc2 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -20,15 +20,14 @@ details. */ #include "security.h" #include "cygwin/version.h" #include "fhandler.h" +#include "path.h" #include "dtable.h" #include "cygheap.h" -#include "path.h" #include "shared_info.h" +#include <assert.h> static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */ -static NO_COPY char fhandler_disk_dummy_name[] = "some disk file"; - struct __cygwin_perfile *perfile_table; DWORD binmode; @@ -146,31 +145,13 @@ fhandler_base::get_readahead_into_buffer (char *buf, size_t buflen) /* Record the file name. Filenames are used mostly for debugging messages, and it's hoped that in cases where the name is really required, the filename wouldn't ever - be too long (e.g. devices or some such). -*/ - + be too long (e.g. devices or some such). */ void fhandler_base::set_name (const char *unix_path, const char *win32_path, int unit) { - if (!no_free_names ()) - { - if (unix_path_name != NULL && unix_path_name != fhandler_disk_dummy_name) - cfree (unix_path_name); - if (win32_path_name != NULL && unix_path_name != fhandler_disk_dummy_name) - cfree (win32_path_name); - } - - unix_path_name = win32_path_name = NULL; if (unix_path == NULL || !*unix_path) return; - unix_path_name = cstrdup (unix_path); - if (unix_path_name == NULL) - { - system_printf ("fatal error. strdup failed"); - exit (ENOMEM); - } - if (win32_path) win32_path_name = cstrdup (win32_path); else @@ -185,6 +166,34 @@ fhandler_base::set_name (const char *unix_path, const char *win32_path, int unit system_printf ("fatal error. strdup failed"); exit (ENOMEM); } + + assert (unix_path_name == NULL); + /* FIXME: This isn't really right. It ignores the first argument if we're + building names for a device and just converts the device name from the + win32 name since it has theoretically been previously detected by + path_conv. Ideally, we should pass in a format string and build the + unix_path, too. */ + if (!is_device () || *win32_path_name != '\\') + unix_path_name = cstrdup (unix_path); + else + { + unix_path_name = cstrdup (win32_path_name); + for (char *p = unix_path_name; (p = strchr (p, '\\')); p++) + *p = '/'; + } + + if (unix_path_name == NULL) + { + system_printf ("fatal error. strdup failed"); + exit (ENOMEM); + } +} + +void +fhandler_base::reset_unix_path_name (const char *unix_path) +{ + cfree (unix_path_name); + unix_path_name = cstrdup (unix_path); } /* Detect if we are sitting at EOF for conditions where Windows @@ -235,6 +244,13 @@ fhandler_base::raw_read (void *ptr, size_t ulen) case ERROR_NOACCESS: if (is_at_eof (get_handle (), errcode)) return 0; + case ERROR_INVALID_FUNCTION: + case ERROR_INVALID_PARAMETER: + if (openflags & O_DIROPEN) + { + set_errno (EISDIR); + return -1; + } default: syscall_printf ("ReadFile %s failed, %E", unix_path_name); __seterrno_from_win_error (errcode); @@ -316,44 +332,28 @@ fhandler_base::open (int flags, mode_t mode) } if (get_query_open ()) - { - access = 0; - } + access = 0; else if (get_device () == FH_TAPE) - { - access = GENERIC_READ | GENERIC_WRITE; - } + access = GENERIC_READ | GENERIC_WRITE; else if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_RDONLY) - { - access = GENERIC_READ; - } + access = GENERIC_READ; else if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_WRONLY) - { - access = GENERIC_WRITE; - } + access = GENERIC_WRITE; else - { - access = GENERIC_READ | GENERIC_WRITE; - } + access = GENERIC_READ | GENERIC_WRITE; /* Allow reliable lseek on disk devices. */ if (get_device () == FH_FLOPPY) - { - access |= GENERIC_READ; - } + access |= GENERIC_READ; /* FIXME: O_EXCL handling? */ if ((flags & O_TRUNC) && ((flags & O_ACCMODE) != O_RDONLY)) { if (flags & O_CREAT) - { - creation_distribution = CREATE_ALWAYS; - } + creation_distribution = CREATE_ALWAYS; else - { - creation_distribution = TRUNCATE_EXISTING; - } + creation_distribution = TRUNCATE_EXISTING; } else if (flags & O_CREAT) creation_distribution = OPEN_ALWAYS; @@ -361,9 +361,7 @@ fhandler_base::open (int flags, mode_t mode) creation_distribution = OPEN_EXISTING; if ((flags & O_EXCL) && (flags & O_CREAT)) - { - creation_distribution = CREATE_NEW; - } + creation_distribution = CREATE_NEW; if (flags & O_APPEND) set_append_p(); @@ -868,9 +866,6 @@ fhandler_disk_file::fstat (struct stat *buf) memset (buf, 0, sizeof (*buf)); - if (is_device ()) - return stat_dev (get_device (), get_unit (), get_namehash (), buf); - /* NT 3.51 seems to have a bug when attempting to get vol serial numbers. This loop gets around this. */ for (int i = 0; i < 2; i++) @@ -1199,6 +1194,8 @@ fhandler_base::fhandler_base (DWORD devtype, const char *name, int unit): raixget (0), raixput (0), rabuflen (0), + unix_path_name (NULL), + win32_path_name (NULL), open_status (0) { status = devtype; @@ -1210,20 +1207,15 @@ fhandler_base::fhandler_base (DWORD devtype, const char *name, int unit): if (!get_w_binset ()) set_w_binary (bin); } - unix_path_name = win32_path_name = NULL; - set_name (name, NULL, unit); } /* Normal I/O destructor */ fhandler_base::~fhandler_base (void) { - if (!no_free_names ()) - { - if (unix_path_name != NULL && unix_path_name != fhandler_disk_dummy_name) - cfree (unix_path_name); - if (win32_path_name != NULL && win32_path_name != fhandler_disk_dummy_name) - cfree (win32_path_name); - } + if (unix_path_name != NULL) + cfree (unix_path_name); + if (win32_path_name != NULL) + cfree (win32_path_name); if (rabuf) free (rabuf); unix_path_name = win32_path_name = NULL; @@ -1236,8 +1228,6 @@ fhandler_disk_file::fhandler_disk_file (const char *name) : fhandler_base (FH_DISK, name) { set_cb (sizeof *this); - set_no_free_names (); - unix_path_name = win32_path_name = fhandler_disk_dummy_name; } int @@ -1260,19 +1250,12 @@ fhandler_disk_file::open (const char *path, int flags, mode_t mode) } set_name (path, real_path.get_win32 ()); - set_no_free_names (0); return open (real_path, flags, mode); } int fhandler_disk_file::open (path_conv& real_path, int flags, mode_t mode) { - if (get_win32_name () == fhandler_disk_dummy_name) - { - win32_path_name = real_path.get_win32 (); - set_no_free_names (); - } - if (real_path.isbinary ()) { set_r_binary (1); @@ -1282,8 +1265,7 @@ fhandler_disk_file::open (path_conv& real_path, int flags, mode_t mode) set_has_acls (real_path.has_acls ()); set_isremote (real_path.isremote ()); - if (real_path.file_attributes () != (DWORD)-1 - && (real_path.file_attributes () & FILE_ATTRIBUTE_DIRECTORY)) + if (real_path.isdir ()) flags |= O_DIROPEN; int res = this->fhandler_base::open (flags, mode); |