OSDN Git Service

* path.cc (symlink_info::check_reparse_point): Always check
authorcorinna <corinna>
Tue, 10 Nov 2009 04:46:35 +0000 (04:46 +0000)
committercorinna <corinna>
Tue, 10 Nov 2009 04:46:35 +0000 (04:46 +0000)
SubstituteName for volume string to recognize volume mount points.
Reuse subst when calling sys_wcstombs.
* syscalls.cc (rename): Set errno to EBUSY when trying to rename
volume mount points.  Explain why.

winsup/cygwin/ChangeLog
winsup/cygwin/path.cc
winsup/cygwin/syscalls.cc

index 3e89d76..4a68aba 100644 (file)
@@ -1,5 +1,13 @@
 2009-11-09  Corinna Vinschen  <corinna@vinschen.de>
 
+       * path.cc (symlink_info::check_reparse_point): Always check
+       SubstituteName for volume string to recognize volume mount points.
+       Reuse subst when calling sys_wcstombs.
+       * syscalls.cc (rename): Set errno to EBUSY when trying to rename
+       volume mount points.  Explain why.
+
+2009-11-09  Corinna Vinschen  <corinna@vinschen.de>
+
        * fhandler_console.cc (fhandler_console::read): Restrict generating
        META key sequences to singlebyte input chars.
 
index 1f95073..daf780e 100644 (file)
@@ -1873,18 +1873,15 @@ symlink_info::check_reparse_point (HANDLE h)
                  (WCHAR *)((char *)rp->MountPointReparseBuffer.PathBuffer
                          + rp->MountPointReparseBuffer.SubstituteNameOffset),
                  rp->MountPointReparseBuffer.SubstituteNameLength);
-      if (rp->MountPointReparseBuffer.PrintNameLength == 0
-         || RtlEqualUnicodePathPrefix (&subst, &ro_u_volume, TRUE))
+      if (RtlEqualUnicodePathPrefix (&subst, &ro_u_volume, TRUE))
        {
          /* Volume mount point.  Not treated as symlink. The return
             value of -1 is a hint for the caller to treat this as a
             volume mount point. */
          return -1;
        }
-      sys_wcstombs (srcbuf, SYMLINK_MAX + 1,
-                   (WCHAR *)((char *)rp->MountPointReparseBuffer.PathBuffer
-                           + rp->MountPointReparseBuffer.SubstituteNameOffset),
-                   rp->MountPointReparseBuffer.SubstituteNameLength / sizeof (WCHAR));
+      sys_wcstombs (srcbuf, SYMLINK_MAX + 1, subst.Buffer,
+                   subst.Length / sizeof (WCHAR));
       pflags = PATH_SYMLINK | PATH_REP;
       fileattr &= ~FILE_ATTRIBUTE_DIRECTORY;
     }
index 55415b6..7a4f239 100644 (file)
@@ -1758,6 +1758,16 @@ rename (const char *oldpath, const char *newpath)
       set_errno (EROFS);
       goto out;
     }
+  if (oldpc.has_attribute (FILE_ATTRIBUTE_REPARSE_POINT) && !oldpc.issymlink ())
+    {
+      /* Volume mount point.  If we try to rename a volume mount point, NT
+        returns STATUS_NOT_SAME_DEVICE ==> Win32 ERROR_NOT_SAME_DEVICE ==>
+        errno EXDEV.  That's bad since mv(1) will now perform a cross-device
+        move.  So what we do here is to treat the volume mount point just
+        like Linux treats a mount point. */
+      set_errno (EBUSY);
+      goto out;
+    }
   if (old_dir_requested && !oldpc.isdir ())
     {
       /* Reject rename("file/","x").  */