OSDN Git Service

Add "path.h" include throughout, where needed. Use new path_conv methods and
authorcgf <cgf>
Mon, 1 Oct 2001 04:10:05 +0000 (04:10 +0000)
committercgf <cgf>
Mon, 1 Oct 2001 04:10:05 +0000 (04:10 +0000)
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.

37 files changed:
winsup/cygwin/ChangeLog
winsup/cygwin/cygheap.cc
winsup/cygwin/dcrt0.cc
winsup/cygwin/dir.cc
winsup/cygwin/dll_init.cc
winsup/cygwin/dtable.cc
winsup/cygwin/dtable.h
winsup/cygwin/fcntl.cc
winsup/cygwin/fhandler.cc
winsup/cygwin/fhandler.h
winsup/cygwin/fhandler_console.cc
winsup/cygwin/fhandler_raw.cc
winsup/cygwin/fhandler_socket.cc
winsup/cygwin/fhandler_tape.cc
winsup/cygwin/fhandler_tty.cc
winsup/cygwin/fork.cc
winsup/cygwin/grp.cc
winsup/cygwin/heap.cc
winsup/cygwin/ioctl.cc
winsup/cygwin/malloc_wrapper.cc
winsup/cygwin/mmap.cc
winsup/cygwin/passwd.cc
winsup/cygwin/path.cc
winsup/cygwin/path.h
winsup/cygwin/pinfo.cc
winsup/cygwin/pipe.cc
winsup/cygwin/poll.cc
winsup/cygwin/select.cc
winsup/cygwin/shared.cc
winsup/cygwin/sigproc.cc
winsup/cygwin/spawn.cc
winsup/cygwin/syscalls.cc
winsup/cygwin/sysconf.cc
winsup/cygwin/syslog.cc
winsup/cygwin/termios.cc
winsup/cygwin/tty.cc
winsup/cygwin/uinfo.cc

index bd81827..bbc17fd 100644 (file)
@@ -1,3 +1,43 @@
+Sun Sep 30 22:51:41 2001  Christopher Faylor <cgf@cygnus.com>
+
+       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.
+
 Sun Sep 30 17:37:43 2001  Christopher Faylor <cgf@cygnus.com>
 
        * environ.cc (winenv): Allocate exact amount of space needed for forced
index c5f6af7..a0e00d3 100644 (file)
@@ -15,8 +15,8 @@
 #include <stdlib.h>
 #include "security.h"
 #include "fhandler.h"
-#include "dtable.h"
 #include "path.h"
+#include "dtable.h"
 #include "cygheap.h"
 #include "child_info.h"
 #include "heap.h"
index f347ade..73c1b72 100644 (file)
@@ -26,8 +26,8 @@ details. */
 #include "perprocess.h"
 #include "security.h"
 #include "fhandler.h"
-#include "dtable.h"
 #include "path.h"
+#include "dtable.h"
 #include "cygheap.h"
 #include "child_info.h"
 #include "perthread.h"
index 7b9b2d6..079c5c4 100644 (file)
@@ -367,79 +367,76 @@ rmdir (const char *dir)
   if (real_dir.error)
     {
       set_errno (real_dir.error);
-      goto done;
+      res = -1;
     }
-
-  /* Does the file exist? */
-  if (real_dir.file_attributes () == (DWORD) -1)
+  else if (!real_dir.exists ())
     {
       set_errno (ENOENT);
-      goto done;
+      res = -1;
     }
-
-  /* Is `dir' a directory? */
-  if  (!(real_dir.file_attributes () & FILE_ATTRIBUTE_DIRECTORY))
+  else if  (!real_dir.isdir ())
     {
       set_errno (ENOTDIR);
-      goto done;
-    }
-
-  /* Even own directories can't be removed if R/O attribute is set. */
-  if (real_dir.file_attributes () & FILE_ATTRIBUTE_READONLY)
-    SetFileAttributes (real_dir.get_win32 (), real_dir.file_attributes () &
-                                             ~FILE_ATTRIBUTE_READONLY);
-
-  if (RemoveDirectoryA (real_dir.get_win32 ()))
-    {
-      /* RemoveDirectory on a samba drive doesn't return an error if the
-        directory can't be removed because it's not empty. Checking for
-        existence afterwards keeps us informed about success. */
-      if (GetFileAttributesA (real_dir.get_win32 ()) != (DWORD) -1)
-       set_errno (ENOTEMPTY);
-      else
-       res = 0;
+      res = -1;
     }
   else
     {
-      /* This kludge detects if we are attempting to remove the current working
-         directory.  If so, we will move elsewhere to potentially allow the
-        rmdir to succeed.  This means that cygwin's concept of the current working
-        directory != Windows concept but, hey, whaddaregonnado?
-        Note that this will not cause something like the following to work:
-                $ cd foo
-                $ rmdir .
-         since the shell will have foo "open" in the above case and so Windows will
-        not allow the deletion.
-        FIXME: A potential workaround for this is for cygwin apps to *never* call
-        SetCurrentDirectory. */
-      if (strcasematch (real_dir, cygheap->cwd.win32)
-         && !strcasematch ("c:\\", cygheap->cwd.win32))
+      /* Even own directories can't be removed if R/O attribute is set. */
+      if (real_dir.has_attribute (FILE_ATTRIBUTE_READONLY))
+       SetFileAttributes (real_dir,
+                          (DWORD) real_dir & ~FILE_ATTRIBUTE_READONLY);
+
+      if (RemoveDirectory (real_dir))
        {
-         DWORD err = GetLastError ();
-         if (!SetCurrentDirectory ("c:\\"))
-           SetLastError (err);
+         /* RemoveDirectory on a samba drive doesn't return an error if the
+            directory can't be removed because it's not empty. Checking for
+            existence afterwards keeps us informed about success. */
+         if (GetFileAttributes (real_dir) != (DWORD) -1)
+           set_errno (ENOTEMPTY);
          else
-           return rmdir (dir);
+           res = 0;
        }
-      if (GetLastError() == ERROR_ACCESS_DENIED)
+      else
        {
+         /* This kludge detects if we are attempting to remove the current working
+            directory.  If so, we will move elsewhere to potentially allow the
+            rmdir to succeed.  This means that cygwin's concept of the current working
+            directory != Windows concept but, hey, whaddaregonnado?
+            Note that this will not cause something like the following to work:
+                    $ cd foo
+                    $ rmdir .
+            since the shell will have foo "open" in the above case and so Windows will
+            not allow the deletion.
+            FIXME: A potential workaround for this is for cygwin apps to *never* call
+            SetCurrentDirectory. */
+         if (strcasematch (real_dir, cygheap->cwd.win32)
+             && !strcasematch ("c:\\", cygheap->cwd.win32))
+           {
+             DWORD err = GetLastError ();
+             if (!SetCurrentDirectory ("c:\\"))
+               SetLastError (err);
+             else if ((res = rmdir (dir)))
+               SetCurrentDirectory (cygheap->cwd.win32);
+           }
+         if (GetLastError () == ERROR_ACCESS_DENIED)
+           {
 
-         /* On 9X ERROR_ACCESS_DENIED is returned if you try to remove
-            a non-empty directory. */
-         if (wincap.access_denied_on_delete ())
-           set_errno (ENOTEMPTY);
+             /* On 9X ERROR_ACCESS_DENIED is returned if you try to remove
+                a non-empty directory. */
+             if (wincap.access_denied_on_delete ())
+               set_errno (ENOTEMPTY);
+             else
+               __seterrno ();
+           }
          else
            __seterrno ();
-       }
-      else
-       __seterrno ();
 
-      /* If directory still exists, restore R/O attribute. */
-      if (real_dir.file_attributes () & FILE_ATTRIBUTE_READONLY)
-       SetFileAttributes (real_dir.get_win32 (), real_dir.file_attributes ());
+         /* If directory still exists, restore R/O attribute. */
+         if (real_dir.has_attribute (FILE_ATTRIBUTE_READONLY))
+           SetFileAttributes (real_dir, real_dir);
+       }
     }
 
-done:
   syscall_printf ("%d = rmdir (%s)", res, dir);
   return res;
 }
index 96bf1bc..d4dcca0 100644 (file)
@@ -15,6 +15,7 @@ details. */
 #include "environ.h"
 #include "security.h"
 #include "fhandler.h"
+#include "path.h"
 #include "dtable.h"
 #include "cygheap.h"
 
index e08ed42..9c86772 100644 (file)
@@ -210,7 +210,8 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle,
        }
     }
 
-  build_fhandler (fd, name, handle)->init (handle, myaccess, bin);
+  path_conv pc;
+  build_fhandler (fd, name, handle, &pc)->init (handle, myaccess, bin);
   set_std_handle (fd);
   paranoid_printf ("fd %d, handle %p", fd, handle);
 }
@@ -228,7 +229,8 @@ cygwin_attach_handle_to_fd (char *name, int fd, HANDLE handle, mode_t bin,
 }
 
 fhandler_base *
-dtable::build_fhandler (int fd, const char *name, HANDLE handle, path_conv *pc)
+dtable::build_fhandler (int fd, const char *name, HANDLE handle, path_conv *pc,
+                       unsigned opt, suffix_info *si)
 {
   int unit;
   DWORD devn;
@@ -238,7 +240,12 @@ dtable::build_fhandler (int fd, const char *name, HANDLE handle, path_conv *pc)
     devn = get_device_number (name, unit);
   else
     {
-      pc->check (name);
+      pc->check (name, opt | PC_NULLEMPTY, si);
+      if (pc->error)
+       {
+         set_errno (pc->error);
+         return NULL;
+       }
       devn = pc->get_devn ();
       unit = pc->get_unitn ();
     }
@@ -268,7 +275,7 @@ dtable::build_fhandler (int fd, const char *name, HANDLE handle, path_conv *pc)
 
   fh = build_fhandler (fd, devn, name, unit);
   if (pc)
-    fh->set_name (name, *pc);
+    fh->set_name (name, *pc, unit);
   return fh;
 }
 
@@ -434,6 +441,14 @@ done:
   return res;
 }
 
+void
+dtable::reset_unix_path_name (int fd, const char *name)
+{
+  SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "reset_unix_name");
+  fds[fd]->reset_unix_path_name (name);
+  ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "reset_unix_name");
+}
+
 select_record *
 dtable::select_read (int fd, select_record *s)
 {
index 7e27bf6..0f00bd0 100644 (file)
@@ -13,6 +13,7 @@ details. */
 
 #include "thread.h"
 
+class suffix_info;
 class dtable
 {
   fhandler_base **fds;
@@ -50,7 +51,8 @@ public:
   fhandler_base *build_fhandler (int fd, DWORD dev, const char *name,
                                 int unit = -1);
   fhandler_base *build_fhandler (int fd, const char *name, HANDLE h = NULL,
-                                path_conv *pc = NULL);
+                                path_conv *pc = NULL,
+                                unsigned opts = PC_SYM_FOLLOW, suffix_info *si = NULL);
   inline int not_open (int fd)
   {
     SetResourceLock (LOCK_FD_LIST, READ_LOCK, "not_open");
@@ -60,6 +62,7 @@ public:
     ReleaseResourceLock (LOCK_FD_LIST, READ_LOCK, "not open");
     return res;
   }
+  void reset_unix_path_name (int fd, const char *name);
   int find_unused_handle (int start);
   int find_unused_handle () { return find_unused_handle (first_fd_for_open);}
   void release (int fd);
index 517cf6e..b531218 100644 (file)
@@ -15,6 +15,7 @@ details. */
 #include <unistd.h>
 #include "security.h"
 #include "fhandler.h"
+#include "path.h"
 #include "dtable.h"
 #include "cygheap.h"
 #include "cygerrno.h"
index a670e78..54adc8d 100644 (file)
@@ -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);
index 8f3368e..59cf14f 100644 (file)
@@ -65,8 +65,7 @@ enum
   FH_W95LSBUG  = 0x00400000,   /* set when lseek is called as a flag that
                                 * _write should check if we've moved beyond
                                 * EOF, zero filling if so. */
-  FH_NOFRNAME  = 0x00800000,   /* Set if shouldn't free unix_path_name and
-                                  windows_path_name_ on destruction. */
+  FH_UNUSED    = 0x00800000,   /* currently unused. */
   FH_NOEINTR   = 0x01000000,   /* Set if I/O should be uninterruptible. */
   FH_FFIXUP    = 0x02000000,   /* Set if need to fixup after fork. */
   FH_LOCAL     = 0x04000000,   /* File is unix domain socket */
@@ -187,6 +186,7 @@ public:
   void set_name (const char * unix_path, const char * win32_path = NULL,
                 int unit = 0);
 
+  void reset_unix_path_name (const char *);
   virtual fhandler_base& operator =(fhandler_base &x);
   fhandler_base (DWORD dev, const char *name = 0, int unit = 0);
   virtual ~fhandler_base ();
@@ -301,10 +301,6 @@ public:
   int isremote () { return FHISSETF (ISREMOTE); }
   void set_isremote (int val) { FHCONDSETF (val, ISREMOTE); }
 
-  int no_free_names () { return FHISSETF (NOFRNAME); }
-  void set_no_free_names (int val) { FHCONDSETF (val, NOFRNAME); }
-  void set_no_free_names () { FHSETF (NOFRNAME); }
-
   const char *get_name () { return unix_path_name; }
   const char *get_win32_name () { return win32_path_name; }
   unsigned long get_namehash () { return namehash; }
index d061dee..9dd98e7 100644 (file)
@@ -24,6 +24,7 @@ details. */
 #include "cygerrno.h"
 #include "security.h"
 #include "fhandler.h"
+#include "path.h"
 #include "dtable.h"
 #include "cygheap.h"
 #include "sync.h"
index 7ed439b..20f2de5 100644 (file)
@@ -20,9 +20,9 @@
 #include "perprocess.h"
 #include "security.h"
 #include "fhandler.h"
+#include "path.h"
 #include "dtable.h"
 #include "cygheap.h"
-#include "path.h"
 
 /* static wrapper functions to hide the effect of media changes and
    bus resets which occurs after a new media is inserted. This is
index dbf284e..a34272f 100644 (file)
@@ -27,6 +27,7 @@
 #include "cygwin/version.h"
 #include "perprocess.h"
 #include "fhandler.h"
+#include "path.h"
 #include "dtable.h"
 #include "cygheap.h"
 #include "sigproc.h"
index 5acbf0f..4856135 100644 (file)
@@ -19,9 +19,9 @@ details. */
 #include "perprocess.h"
 #include "security.h"
 #include "fhandler.h"
+#include "path.h"
 #include "dtable.h"
 #include "cygheap.h"
-#include "path.h"
 
 /**********************************************************************/
 /* fhandler_dev_tape */
index 1a46ecb..03f7d81 100644 (file)
@@ -19,6 +19,7 @@ details. */
 #include "cygerrno.h"
 #include "security.h"
 #include "fhandler.h"
+#include "path.h"
 #include "dtable.h"
 #include "sync.h"
 #include "sigproc.h"
@@ -441,11 +442,6 @@ fhandler_tty_slave::fhandler_tty_slave (int num, const char *name) :
 {
   set_cb (sizeof *this);
   ttynum = num;
-  /* FIXME: This is wasteful.  We should rewrite the set_name path to eliminate the
-     need for double allocates. */
-  unix_path_name = (char *) crealloc (unix_path_name, strlen (win32_path_name) + 1);
-  strcpy (unix_path_name, win32_path_name);
-  unix_path_name[0] = unix_path_name[4] = '/';
   debug_printf ("unix '%s', win32 '%s'", unix_path_name, win32_path_name);
   inuse = NULL;
 }
index ffd48e4..640ae27 100644 (file)
@@ -17,6 +17,7 @@ details. */
 #include <errno.h>
 #include "security.h"
 #include "fhandler.h"
+#include "path.h"
 #include "dtable.h"
 #include "cygerrno.h"
 #include "sync.h"
index d9e7b02..87cc4b4 100644 (file)
@@ -22,8 +22,8 @@ details. */
 #include "pinfo.h"
 #include "security.h"
 #include "fhandler.h"
-#include "dtable.h"
 #include "path.h"
+#include "dtable.h"
 #include "cygheap.h"
 #include "cygerrno.h"
 #include "pwdgrp.h"
index 1a3c2a8..eaa500c 100644 (file)
@@ -18,6 +18,7 @@ details. */
 #include "shared_info.h"
 #include "security.h"
 #include "fhandler.h"
+#include "path.h"
 #include "dtable.h"
 #include "cygheap.h"
 
index f02c71c..93fe9dd 100644 (file)
@@ -17,6 +17,7 @@ details. */
 #include "cygerrno.h"
 #include "security.h"
 #include "fhandler.h"
+#include "path.h"
 #include "dtable.h"
 #include "cygheap.h"
 #include <sys/termios.h>
index 1cbe43c..2fa93b1 100644 (file)
@@ -16,6 +16,7 @@ details. */
 #include <assert.h>
 #include "security.h"
 #include "fhandler.h"
+#include "path.h"
 #include "dtable.h"
 #include "cygheap.h"
 #include "heap.h"
index 4ebc017..c13a3f3 100644 (file)
@@ -16,6 +16,7 @@ details. */
 #include <errno.h>
 #include "security.h"
 #include "fhandler.h"
+#include "path.h"
 #include "dtable.h"
 #include "cygerrno.h"
 #include "cygheap.h"
index 092473b..2f52473 100644 (file)
@@ -16,8 +16,8 @@ details. */
 #include "cygerrno.h"
 #include "security.h"
 #include "fhandler.h"
-#include "dtable.h"
 #include "path.h"
+#include "dtable.h"
 #include "sync.h"
 #include "sigproc.h"
 #include "pinfo.h"
index 1c7c554..2aa19e1 100644 (file)
@@ -2428,8 +2428,7 @@ symlink (const char *topath, const char *frompath)
 
   syscall_printf ("symlink (%s, %s)", topath, win32_path.get_win32 ());
 
-  if (win32_path.is_device () ||
-      win32_path.file_attributes () != (DWORD) -1)
+  if (win32_path.is_device () || win32_path.exists ())
     {
       set_errno (EEXIST);
       goto done;
@@ -2897,7 +2896,7 @@ readlink (const char *path, char *buf, int buflen)
       return -1;
     }
 
-  if (pathbuf.file_attributes () == (DWORD) -1)
+  if (!pathbuf.exists ())
     {
       set_errno (ENOENT);
       return -1;
@@ -3106,8 +3105,9 @@ fchdir (int fd)
       set_errno (EBADF);
       return -1;
     }
+  SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "fchdir");
   int ret = chdir (cygheap->fdtab[fd]->get_name ());
-  if (!ret)
+  if (ret == 0)
     {
       /* The name in the fhandler is explicitely overwritten with the full path.
         Otherwise fchmod() to a path originally given as a relative path could
@@ -3119,13 +3119,11 @@ fchdir (int fd)
 
         The 2nd fchmod should chdir to the same dir as the first call, not
         to it's parent dir. */
-      char path[MAX_PATH];
       char posix_path[MAX_PATH];
-      mount_table->conv_to_posix_path (cygheap->cwd.get (path, 0, 1),
-                                      posix_path, 0);
-      cygheap->fdtab[fd]->set_name (path, posix_path);
+      cygheap->fdtab.reset_unix_path_name (fd, cygheap->cwd.get (posix_path, 1, 1));
     }
 
+  ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "fchdir");
   syscall_printf ("%d = fchdir (%d)", ret, fd);
   return ret;
 }
index a3e94c1..17f5e2b 100644 (file)
@@ -69,6 +69,12 @@ class path_conv
  public:
 
   unsigned path_flags;
+  char *known_suffix;
+  int error;
+  DWORD devn;
+  int unit;
+  DWORD fileattr;
+  BOOL case_clash;
 
   int isdisk () const { return path_flags & PATH_ISDISK;}
   int isremote () const {return is_remote_drive;}
@@ -80,6 +86,9 @@ class path_conv
   int issymlink () const {return path_flags & PATH_SYMLINK;}
   int issocket () const {return path_flags & PATH_SOCKET;}
   int iscygexec () const {return path_flags & PATH_CYGWIN_EXEC;}
+  bool exists () const {return fileattr != (DWORD) -1;}
+  bool has_attribute (DWORD x) const {return exists () && (fileattr & x);}
+  int isdir () const {return has_attribute (FILE_ATTRIBUTE_DIRECTORY);}
   executable_states exec_state ()
   {
     extern int _check_for_executable;
@@ -100,16 +109,6 @@ class path_conv
   void set_has_acls (int x = 1) {path_flags |= x ? PATH_HASACLS : PATH_NOTHING;}
   void set_has_buggy_open (int x = 1) {path_flags |= x ? PATH_HASBUGGYOPEN : PATH_NOTHING;}
 
-  char *known_suffix;
-
-  int error;
-  DWORD devn;
-  int unit;
-
-  DWORD fileattr;
-
-  BOOL case_clash;
-
   void check (const char *src, unsigned opt = PC_SYM_FOLLOW,
              const suffix_info *suffixes = NULL)  __attribute__ ((regparm(3)));
 
@@ -129,6 +128,8 @@ class path_conv
 
   inline char *get_win32 () { return path; }
   operator char *() {return path; }
+  operator DWORD &() {return fileattr; }
+  operator int &() {return (int) fileattr; }
   BOOL is_device () {return devn != FH_BAD;}
   DWORD get_devn () {return devn == FH_BAD ? (DWORD) FH_DISK : devn;}
   short get_unitn () {return devn == FH_BAD ? 0 : unit;}
index 14eba9b..6e66e47 100644 (file)
@@ -15,6 +15,7 @@ details. */
 #include <limits.h>
 #include "security.h"
 #include "fhandler.h"
+#include "path.h"
 #include "dtable.h"
 #include "cygerrno.h"
 #include "sync.h"
index 03af862..099aa37 100644 (file)
@@ -15,6 +15,7 @@ details. */
 #include "cygerrno.h"
 #include "security.h"
 #include "fhandler.h"
+#include "path.h"
 #include "dtable.h"
 #include "cygheap.h"
 #include "thread.h"
index 9b85f20..2ac6068 100644 (file)
@@ -14,6 +14,7 @@
 #include <errno.h>
 #include "security.h"
 #include "fhandler.h"
+#include "path.h"
 #include "dtable.h"
 #include "cygheap.h"
 #include "cygerrno.h"
index 2307e29..e66d078 100644 (file)
@@ -36,6 +36,7 @@ details. */
 #include "cygerrno.h"
 #include "security.h"
 #include "fhandler.h"
+#include "path.h"
 #include "dtable.h"
 #include "cygheap.h"
 #include "sync.h"
index 8ce88d2..81d39e3 100644 (file)
@@ -19,6 +19,7 @@ details. */
 #include "pinfo.h"
 #include "security.h"
 #include "fhandler.h"
+#include "path.h"
 #include "dtable.h"
 #include "cygheap.h"
 #include "heap.h"
index 7f621d3..7b55487 100644 (file)
@@ -23,6 +23,7 @@ details. */
 #include "pinfo.h"
 #include "security.h"
 #include "fhandler.h"
+#include "path.h"
 #include "dtable.h"
 #include "cygheap.h"
 #include "child_info.h"
index 248dd42..0a0a84d 100644 (file)
@@ -63,10 +63,10 @@ perhaps_suffix (const char *prog, path_conv &buf)
   debug_printf ("prog '%s'", prog);
   buf.check (prog, PC_SYM_FOLLOW | PC_FULL, std_suffixes);
 
-  if (buf.file_attributes () & FILE_ATTRIBUTE_DIRECTORY)
+  if (buf.isdir ())
     ext = NULL;
   else if (buf.known_suffix)
-    ext = buf + (buf.known_suffix - buf.get_win32 ());
+    ext = (char *) buf + (buf.known_suffix - buf.get_win32 ());
   else
     ext = strchr (buf, '\0');
 
index 9f5c8ac..9aa1dd7 100644 (file)
@@ -116,16 +116,13 @@ _unlink (const char *ourname)
 
   syscall_printf ("_unlink (%s)", win32_name.get_win32 ());
 
-  DWORD atts;
-  atts = win32_name.file_attributes ();
-  if (atts == 0xffffffff)
+  if (!win32_name.exists ())
     {
-      syscall_printf ("unlinking a nonexistant file");
+      syscall_printf ("unlinking a nonexistent file");
       set_errno (ENOENT);
       goto done;
     }
-
-  if (atts & FILE_ATTRIBUTE_DIRECTORY)
+  else if (win32_name.isdir ())
     {
       syscall_printf ("unlinking a directory");
       set_errno (EPERM);
@@ -140,11 +137,11 @@ _unlink (const char *ourname)
     }
 
   /* Check for shortcut as symlink condition. */
-  if (atts & FILE_ATTRIBUTE_READONLY)
+  if (win32_name.has_attribute (FILE_ATTRIBUTE_READONLY))
     {
       int len = strlen (win32_name);
-      if (len > 4 && strcasematch (win32_name + len - 4, ".lnk"))
-       SetFileAttributes (win32_name, atts & ~FILE_ATTRIBUTE_READONLY);
+      if (len > 4 && strcasematch ((char *) win32_name + len - 4, ".lnk"))
+       SetFileAttributes (win32_name, (DWORD) win32_name & ~FILE_ATTRIBUTE_READONLY);
     }
 
   DWORD lasterr;
@@ -249,11 +246,7 @@ remove (const char *ourname)
       return -1;
     }
 
-  DWORD atts = win32_name.file_attributes ();
-  if (atts != 0xffffffff && atts & FILE_ATTRIBUTE_DIRECTORY)
-    return rmdir (ourname);
-
-  return _unlink (ourname);
+  return win32_name.isdir () ? rmdir (ourname) : _unlink (ourname);
 }
 
 extern "C" pid_t
@@ -619,7 +612,7 @@ _link (const char *a, const char *b)
       goto done;
     }
 
-  if (real_b.file_attributes () != (DWORD)-1)
+  if (real_b.exists ())
     {
       syscall_printf ("file '%s' exists?", (char *)real_b);
       set_errno (EEXIST);
@@ -779,7 +772,7 @@ chown_worker (const char *name, unsigned fmode, uid_t uid, gid_t gid)
        }
 
       DWORD attrib = 0;
-      if (win32_path.file_attributes () & FILE_ATTRIBUTE_DIRECTORY)
+      if (win32_path.isdir ())
        attrib |= S_IFDIR;
       res = get_file_attribute (win32_path.has_acls (),
                                win32_path.get_win32 (),
@@ -792,12 +785,10 @@ chown_worker (const char *name, unsigned fmode, uid_t uid, gid_t gid)
            uid = old_uid;
          if (gid == (gid_t) -1)
            gid = old_gid;
-         if (win32_path.file_attributes () & FILE_ATTRIBUTE_DIRECTORY)
+         if (win32_path.isdir())
            attrib |= S_IFDIR;
-         res = set_file_attribute (win32_path.has_acls (),
-                                   win32_path.get_win32 (),
-                                   uid, gid, attrib,
-                                   cygheap->user.logsrv ());
+         res = set_file_attribute (win32_path.has_acls (), win32_path, uid,
+                                   gid, attrib, cygheap->user.logsrv ());
        }
       if (res != 0 && (!win32_path.has_acls () || !allow_ntsec))
        {
@@ -886,28 +877,25 @@ chmod (const char *path, mode_t mode)
       goto done;
     }
 
-  if (win32_path.file_attributes () == (DWORD)-1)
+  if (!win32_path.exists ())
     __seterrno ();
   else
     {
-      DWORD attr = win32_path.file_attributes ();
       /* temporary erase read only bit, to be able to set file security */
-      SetFileAttributesA (win32_path.get_win32 (),
-                         attr & ~FILE_ATTRIBUTE_READONLY);
+      SetFileAttributes (win32_path, (DWORD) win32_path & ~FILE_ATTRIBUTE_READONLY);
 
       uid_t uid;
       gid_t gid;
 
-      if (win32_path.file_attributes () & FILE_ATTRIBUTE_DIRECTORY)
+      if (win32_path.isdir ())
        mode |= S_IFDIR;
       get_file_attribute (win32_path.has_acls (),
                          win32_path.get_win32 (),
                          NULL, &uid, &gid);
-      if (win32_path.file_attributes () & FILE_ATTRIBUTE_DIRECTORY)
+      /* FIXME: Do we really need this to be specified twice? */
+      if (win32_path.isdir ())
        mode |= S_IFDIR;
-      if (!set_file_attribute (win32_path.has_acls (),
-                               win32_path.get_win32 (),
-                               uid, gid,
+      if (!set_file_attribute (win32_path.has_acls (), win32_path, uid, gid,
                                mode, cygheap->user.logsrv ())
          && allow_ntsec)
        res = 0;
@@ -915,14 +903,14 @@ chmod (const char *path, mode_t mode)
       /* if the mode we want has any write bits set, we can't
         be read only. */
       if (mode & (S_IWUSR | S_IWGRP | S_IWOTH))
-       attr &= ~FILE_ATTRIBUTE_READONLY;
+       (DWORD) win32_path &= ~FILE_ATTRIBUTE_READONLY;
       else
-       attr |= FILE_ATTRIBUTE_READONLY;
+       (DWORD) win32_path |= FILE_ATTRIBUTE_READONLY;
 
       if (S_ISLNK (mode) || S_ISSOCK (mode))
-       attr |= FILE_ATTRIBUTE_SYSTEM;
+       (DWORD) win32_path |= FILE_ATTRIBUTE_SYSTEM;
 
-      if (!SetFileAttributesA (win32_path.get_win32 (), attr))
+      if (!SetFileAttributes (win32_path, win32_path))
        __seterrno ();
       else
        {
@@ -1084,22 +1072,24 @@ stat_worker (const char *caller, const char *name, struct stat *buf,
             int nofollow)
 {
   int res = -1;
-  int oret = 1;
-  int atts;
-
-  int attribute = 0;
+  int oret;
   uid_t uid;
   gid_t gid;
-
-  UINT dtype;
-  fhandler_disk_file fh (NULL);
+  path_conv real_path;
+  fhandler_base *fh = NULL;
 
   MALLOC_CHECK;
+  int open_flags = O_RDONLY | O_BINARY | O_DIROPEN
+                  | (nofollow ? O_NOSYMLINK : 0);
 
   debug_printf ("%s (%s, %p)", caller, name, buf);
 
-  path_conv real_path (name, (nofollow ? PC_SYM_NOFOLLOW : PC_SYM_FOLLOW) |
-                                        PC_FULL, stat_suffixes);
+  if (check_null_invalid_struct_errno (buf))
+    goto done;
+
+  fh = cygheap->fdtab.build_fhandler (-1, name, NULL, &real_path,
+                                     (nofollow ? PC_SYM_NOFOLLOW : PC_SYM_FOLLOW)
+                                     | PC_FULL, stat_suffixes);
 
   if (real_path.error)
     {
@@ -1107,83 +1097,66 @@ stat_worker (const char *caller, const char *name, struct stat *buf,
       goto done;
     }
 
-  if (check_null_invalid_struct_errno (buf))
-    goto done;
-
   memset (buf, 0, sizeof (struct stat));
 
   if (real_path.is_device ())
     return stat_dev (real_path.get_devn (), real_path.get_unitn (),
                     hash_path_name (0, real_path.get_win32 ()), buf);
 
-  atts = real_path.file_attributes ();
-
-  debug_printf ("%d = file_attributes for '%s'", atts, real_path.get_win32 ());
+  debug_printf ("%d = file_attributes for '%s'", (DWORD) real_path,
+               (char *) real_path);
 
-  dtype = real_path.get_drive_type ();
-
-  if ((atts == -1 || ! (atts & FILE_ATTRIBUTE_DIRECTORY) ||
-       (wincap.can_open_directories ()
-       && dtype != DRIVE_NO_ROOT_DIR
-       && dtype != DRIVE_UNKNOWN)))
+  if ((oret = fh->open (real_path, open_flags, 0)))
+    /* ok */;
+  else
     {
-      oret = fh.open (real_path, O_RDONLY | O_BINARY | O_DIROPEN |
-                                (nofollow ? O_NOSYMLINK : 0), 0);
+      int ntsec_atts = 0;
       /* If we couldn't open the file, try a "query open" with no permissions.
         This will allow us to determine *some* things about the file, at least. */
-      if (!oret)
-       {
-         fh.set_query_open (TRUE);
-         oret = fh.open (real_path, O_RDONLY | O_BINARY | O_DIROPEN |
-                                    (nofollow ? O_NOSYMLINK : 0), 0);
-       }
-      /* Check a special case here. If ntsec is ON it happens
-        that a process creates a file using mode 000 to disallow
-        other processes access. In contrast to UNIX, this results
-        in a failing open call in the same process. Check that
-        case. */
-      if (!oret && allow_ntsec && get_errno () == EACCES
-         && !get_file_attribute (TRUE, real_path, &attribute, &uid, &gid)
-         && !attribute && uid == myself->uid && gid == myself->gid)
-       {
+      fh->set_query_open (TRUE);
+      if ((oret = fh->open (real_path, open_flags, 0)))
+        /* ok */;
+      else if (allow_ntsec && real_path.has_acls () && get_errno () == EACCES
+               && !get_file_attribute (TRUE, real_path, &ntsec_atts, &uid, &gid)
+               && !ntsec_atts && uid == myself->uid && gid == myself->gid)
+        {
+         /* Check a special case here. If ntsec is ON it happens
+            that a process creates a file using mode 000 to disallow
+            other processes access. In contrast to UNIX, this results
+            in a failing open call in the same process. Check that
+            case. */
          set_file_attribute (TRUE, real_path, 0400);
-         oret = fh.open (real_path, O_RDONLY | O_BINARY | O_DIROPEN |
-                                    (nofollow ? O_NOSYMLINK : 0), 0);
-         set_file_attribute (TRUE, real_path.get_win32 (), 0);
-       }
-      if (oret)
-       {
-         res = fh.fstat (buf);
-         fh.close ();
-         /* The number of links to a directory includes the
-            number of subdirectories in the directory, since all
-            those subdirectories point to it.
-            This is too slow on remote drives, so we do without it and
-            set the number of links to 2. */
-         /* Unfortunately the count of 2 confuses `find (1)' command. So
-            let's try it with `1' as link count. */
-         if (atts != -1 && (atts & FILE_ATTRIBUTE_DIRECTORY))
-           buf->st_nlink = (dtype == DRIVE_REMOTE
-                            ? 1
-                            : num_entries (real_path.get_win32 ()));
-         goto done;
-       }
-    }
-  if (atts != -1 && (oret || (!oret && get_errno () != ENOENT
-                                   && get_errno () != ENOSHARE)))
+         oret = fh->open (real_path, open_flags, 0);
+         set_file_attribute (TRUE, real_path, ntsec_atts);
+        }
+    }
+  if (oret)
+    {
+      res = fh->fstat (buf);
+      /* The number of links to a directory includes the
+        number of subdirectories in the directory, since all
+        those subdirectories point to it.
+        This is too slow on remote drives, so we do without it and
+        set the number of links to 2. */
+      /* Unfortunately the count of 2 confuses `find (1)' command. So
+        let's try it with `1' as link count. */
+      if (real_path.isdir ())
+       buf->st_nlink = (real_path.isremote ()
+                        ? 1 : num_entries (real_path.get_win32 ()));
+      fh->close ();
+    }
+  else if (real_path.exists ())
     {
       /* Unfortunately, the above open may fail if the file exists, though.
         So we have to care for this case here, too. */
       WIN32_FIND_DATA wfd;
       HANDLE handle;
       buf->st_nlink = 1;
-      if (atts != -1
-         && (atts & FILE_ATTRIBUTE_DIRECTORY)
-         && dtype != DRIVE_REMOTE)
+      if (real_path.isdir () && real_path.isremote ())
        buf->st_nlink = num_entries (real_path.get_win32 ());
       buf->st_dev = FHDEVN (FH_DISK) << 8;
       buf->st_ino = hash_path_name (0, real_path.get_win32 ());
-      if (atts != -1 && (atts & FILE_ATTRIBUTE_DIRECTORY))
+      if (real_path.isdir ())
        buf->st_mode = S_IFDIR;
       else if (real_path.issymlink ())
        buf->st_mode = S_IFLNK;
@@ -1197,7 +1170,7 @@ stat_worker (const char *caller, const char *name, struct stat *buf,
                                 &buf->st_uid, &buf->st_gid))
        {
          buf->st_mode |= STD_RBITS | STD_XBITS;
-         if ((atts & FILE_ATTRIBUTE_READONLY) == 0)
+         if (!(real_path.has_attribute (FILE_ATTRIBUTE_READONLY)))
            buf->st_mode |= STD_WBITS;
          if (real_path.issymlink ())
            buf->st_mode |= S_IRWXU | S_IRWXG | S_IRWXO;
@@ -1220,6 +1193,8 @@ stat_worker (const char *caller, const char *name, struct stat *buf,
     }
 
  done:
+  if (fh)
+    delete fh;
   MALLOC_CHECK;
   syscall_printf ("%d = %s (%s, %p)", res, caller, name, buf);
   return res;
@@ -1360,7 +1335,7 @@ _rename (const char *oldpath, const char *newpath)
       return -1;
     }
 
-  if (real_old.file_attributes () == (DWORD) -1) /* file to move doesn't exist */
+  if (!real_old.exists ()) /* file to move doesn't exist */
     {
        syscall_printf ("file to move doesn't exist");
        set_errno (ENOENT);
@@ -1369,10 +1344,8 @@ _rename (const char *oldpath, const char *newpath)
 
   /* Destination file exists and is read only, change that or else
      the rename won't work. */
-  if (real_new.file_attributes () != (DWORD) -1 &&
-      real_new.file_attributes () & FILE_ATTRIBUTE_READONLY)
-    SetFileAttributesA (real_new.get_win32 (),
-                       real_new.file_attributes () & ~FILE_ATTRIBUTE_READONLY);
+  if (real_new.has_attribute (FILE_ATTRIBUTE_READONLY))
+    SetFileAttributes (real_new, (DWORD) real_new & ~FILE_ATTRIBUTE_READONLY);
 
   /* Shortcut hack No. 2, part 1 */
   if (!real_old.issymlink () && !real_new.error && real_new.issymlink () &&
@@ -1421,14 +1394,13 @@ done:
     {
       __seterrno ();
       /* Reset R/O attributes if neccessary. */
-      if (real_new.file_attributes () != (DWORD) -1 &&
-         real_new.file_attributes () & FILE_ATTRIBUTE_READONLY)
-       SetFileAttributesA (real_new.get_win32 (), real_new.file_attributes ());
+      if (real_new.has_attribute (FILE_ATTRIBUTE_READONLY))
+       SetFileAttributes (real_new, real_new);
     }
   else
     {
       /* make the new file have the permissions of the old one */
-      SetFileAttributesA (real_new.get_win32 (), real_old.file_attributes ());
+      SetFileAttributes (real_new, real_old);
 
       /* Shortcut hack, No. 2, part 2 */
       /* if the new filename was an existing shortcut, remove it now if the
@@ -1436,12 +1408,12 @@ done:
       if (lnk_suffix)
        {
          *lnk_suffix = '.';
-         DeleteFile (real_new.get_win32 ());
+         DeleteFile (real_new);
        }
     }
 
-  syscall_printf ("%d = rename (%s, %s)", res, real_old.get_win32 (),
-                 real_new.get_win32 ());
+  syscall_printf ("%d = rename (%s, %s)", res, (char *) real_old,
+                 (char *) real_new);
 
   return res;
 }
@@ -2317,27 +2289,29 @@ extern "C" int
 chroot (const char *newroot)
 {
   sigframe thisframe (mainthread);
-  int ret = -1;
   path_conv path (newroot, PC_SYM_FOLLOW | PC_FULL);
 
+  int ret;
   if (path.error)
-    goto done;
-  if (path.file_attributes () == (DWORD)-1)
+    ret = -1;
+  else if (!path.exists ())
     {
       set_errno (ENOENT);
-      goto done;
+      ret = -1;
     }
-  if (!(path.file_attributes () & FILE_ATTRIBUTE_DIRECTORY))
+  else if (!path.isdir ())
     {
       set_errno (ENOTDIR);
-      goto done;
+      ret = -1;
+    }
+  else
+    {
+      char buf[MAX_PATH];
+      normalize_posix_path (newroot, buf);
+      cygheap->root.set (buf, path);
+      ret = 0;
     }
-  char buf[MAX_PATH];
-  normalize_posix_path (newroot, buf);
-  cygheap->root.set (buf, path);
-  ret = 0;
 
-done:
   syscall_printf ("%d = chroot (%s)", ret ? get_errno () : 0,
                                      newroot ? newroot : "NULL");
   return ret;
index aa19091..5e1d91b 100644 (file)
@@ -16,6 +16,7 @@ details. */
 #include <ntdef.h>
 #include "security.h"
 #include "fhandler.h"
+#include "path.h"
 #include "dtable.h"
 #include "cygheap.h"
 #include "cygerrno.h"
index c11ff11..66e9ed1 100644 (file)
@@ -16,6 +16,7 @@ details. */
 #include <unistd.h>
 #include "security.h"
 #include "fhandler.h"
+#include "path.h"
 #include "dtable.h"
 #include "cygerrno.h"
 #include "cygheap.h"
index a2674aa..5488185 100644 (file)
@@ -17,6 +17,7 @@ details. */
 #include "cygerrno.h"
 #include "security.h"
 #include "fhandler.h"
+#include "path.h"
 #include "dtable.h"
 #include "cygheap.h"
 #include "cygwin/version.h"
index b3d753c..ec3f95e 100644 (file)
@@ -18,6 +18,7 @@ details. */
 #include "cygerrno.h"
 #include "security.h"
 #include "fhandler.h"
+#include "path.h"
 #include "dtable.h"
 #include "cygheap.h"
 #include "sync.h"
index a6b94c8..9bbbe9e 100644 (file)
@@ -23,6 +23,7 @@ details. */
 #include "pinfo.h"
 #include "security.h"
 #include "fhandler.h"
+#include "path.h"
 #include "dtable.h"
 #include "cygheap.h"
 #include "registry.h"