This is the mail archive of the cygwin-patches mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [1.7] rename/renameat error


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

According to Eric Blake on 9/22/2009 3:02 PM:
> I've got a patch in testing for both of these issues.

Does this look okay to apply?  The fix in path.cc affects more than just
link, hence I had to add a new option to keep mkdir("d/",mode) still
working, while link("file","d/") now fails with the same ENOENT as Linux.
 rename was tricky, as rename("file","d/") must fail whether or not d
exists, while rename("dir","d/") must succeed if d does not exist or
exists and is empty.  I think I got it all, but it can't hurt to
double-check things.

2009-09-23  Eric Blake  <ebb9@byu.net>

	* path.h (PC_MKDIR): New enum value.
	* path.cc (check): Ensure 'a/' resolves to a directory.
	* syscalls.cc (link): Fix comment.
	(rename): Use correct errno for trailing '.'.  Allow trailing
	slash to newpath iff oldpath is directory.
	* dir.cc (mkdir): Allow trailing slash.

- --
Don't work too hard, make some time for fun as well!

Eric Blake             ebb9@byu.net
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkq6G5EACgkQ84KuGfSFAYBNZQCgmmW5addUf28is9/4MvAlcaTs
9NsAn3Y8CYG2DdIgFT9I6EzhnhtmuklX
=LtpR
-----END PGP SIGNATURE-----
Index: dir.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/dir.cc,v
retrieving revision 1.123
diff -u -p -r1.123 dir.cc
--- dir.cc	28 Nov 2008 09:04:35 -0000	1.123
+++ dir.cc	23 Sep 2009 12:58:26 -0000
@@ -1,6 +1,6 @@
 /* dir.cc: Posix directory-related routines
 
-   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2006, 2007 Red Hat, Inc.
+   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2006, 2007, 2009 Red Hat, Inc.
 
 This file is part of Cygwin.
 
@@ -278,7 +278,7 @@ mkdir (const char *dir, mode_t mode)
   if (efault.faulted (EFAULT))
     return -1;
 
-  if (!(fh = build_fh_name (dir, NULL, PC_SYM_NOFOLLOW)))
+  if (!(fh = build_fh_name (dir, NULL, PC_SYM_NOFOLLOW | PC_MKDIR)))
     goto done;   /* errno already set */;
 
   if (fh->error ())
Index: path.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/path.cc,v
retrieving revision 1.565
diff -u -p -r1.565 path.cc
--- path.cc	22 Sep 2009 09:24:30 -0000	1.565
+++ path.cc	23 Sep 2009 12:58:26 -0000
@@ -622,8 +622,8 @@ path_conv::check (const char *src, unsig
   char *tmp_buf = tp.t_get ();
   char *THIS_path = tp.c_get ();
   symlink_info sym;
-  bool need_directory = 0;
-  bool saw_symlinks = 0;
+  bool need_directory = false;
+  bool saw_symlinks = false;
   bool add_ext = false;
   bool is_relpath;
   char *tail, *path_end;
@@ -698,7 +698,7 @@ path_conv::check (const char *src, unsig
 	 into account during processing */
       if (tail > path_copy + 2 && isslash (tail[-1]))
 	{
-	  need_directory = 1;
+	  need_directory = !(opt & PC_MKDIR);
 	  *--tail = '\0';
 	}
       path_end = tail;
@@ -899,7 +899,7 @@ is_virtual_symlink:
 	     these operations again on the newly derived path. */
 	  else if (symlen > 0)
 	    {
-	      saw_symlinks = 1;
+	      saw_symlinks = true;
 	      if (component == 0 && !need_directory && !(opt & PC_SYM_FOLLOW))
 		{
 		  set_symlink (symlen); // last component of path is a symlink.
@@ -914,7 +914,7 @@ is_virtual_symlink:
 	      else
 		break;
 	    }
-	  else if (sym.error && sym.error != ENOENT)
+	  else if (sym.error && (sym.error != ENOENT || need_directory))
 	    {
 	      error = sym.error;
 	      goto out;
Index: path.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/path.h,v
retrieving revision 1.136
diff -u -p -r1.136 path.h
--- path.h	26 Aug 2009 20:32:35 -0000	1.136
+++ path.h	23 Sep 2009 12:58:26 -0000
@@ -1,7 +1,7 @@
 /* path.h: path data structures
 
    Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
-   2006, 2007, 2008 Red Hat, Inc.
+   2006, 2007, 2008, 2009 Red Hat, Inc.
 
 This file is part of Cygwin.
 
@@ -49,15 +49,16 @@ extern suffix_info stat_suffixes[];
 
 enum pathconv_arg
 {
-  PC_SYM_FOLLOW		= 0x0001,
-  PC_SYM_NOFOLLOW	= 0x0002,
-  PC_SYM_CONTENTS	= 0x0008,
-  PC_NOFULL		= 0x0010,
-  PC_NULLEMPTY		= 0x0020,
-  PC_CHECK_EA		= 0x0040,
-  PC_POSIX		= 0x0080,
-  PC_NOWARN		= 0x0100,
-  PC_NO_ACCESS_CHECK	= 0x00800000
+  PC_SYM_FOLLOW		= 0x0001,	/* Resolve all symlinks.  */
+  PC_SYM_NOFOLLOW	= 0x0002,	/* Operate on symlink.  */
+  PC_SYM_CONTENTS	= 0x0008,	/* Perform readlink.  */
+  PC_NOFULL		= 0x0010,	/* Leave relative path short.  */
+  PC_NULLEMPTY		= 0x0020,	/* Reject "" with ENOENT.  */
+  PC_CHECK_EA		= 0x0040,	/* Unused?  */
+  PC_POSIX		= 0x0080,	/* Expect / separator.  */
+  PC_NOWARN		= 0x0100,	/* Don't warn about DOS names.  */
+  PC_MKDIR		= 0x0200,	/* About to be created via mkdir.  */
+  PC_NO_ACCESS_CHECK	= 0x00800000	/* Skip access check on tail.  */
 };
 
 #define PC_NONULLEMPTY -1
Index: syscalls.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/syscalls.cc,v
retrieving revision 1.533
diff -u -p -r1.533 syscalls.cc
--- syscalls.cc	22 Sep 2009 12:13:53 -0000	1.533
+++ syscalls.cc	23 Sep 2009 12:58:26 -0000
@@ -1124,12 +1124,7 @@ isatty (int fd)
 }
 EXPORT_ALIAS (isatty, _isatty)
 
-/* Under NT, try to make a hard link using backup API.  If that
-   fails or we are Win 95, just copy the file.
-   FIXME: We should actually be checking partition type, not OS.
-   Under NTFS, we should support hard links.  On FAT partitions,
-   we should just copy the file.
-*/
+/* Under NT, try to make a hard link using backup API.  */
 
 extern "C" int
 link (const char *oldpath, const char *newpath)
@@ -1650,13 +1645,13 @@ rename (const char *oldpath, const char 
   if (has_dot_last_component (oldpath, true))
     {
       oldpc.check (oldpath, PC_SYM_NOFOLLOW, stat_suffixes);
-      set_errno (oldpc.isdir () ? EBUSY : ENOTDIR);
+      set_errno (oldpc.isdir () ? EINVAL : ENOTDIR);
       goto out;
     }
   if (has_dot_last_component (newpath, true))
     {
       newpc.check (newpath, PC_SYM_NOFOLLOW, stat_suffixes);
-      set_errno (!newpc.exists () ? ENOENT : newpc.isdir () ? EBUSY : ENOTDIR);
+      set_errno (!newpc.exists () ? ENOENT : newpc.isdir () ? EINVAL : ENOTDIR);
       goto out;
     }
 
@@ -1701,6 +1696,11 @@ rename (const char *oldpath, const char 
   nlen = strlen (newpath);
   if (isdirsep (newpath[nlen - 1]))
     {
+      if (!oldpc.isdir())
+	{
+	  set_errno (ENOTDIR);
+	  goto out;
+	}
       stpcpy (newbuf = tp.c_get (), newpath);
       while (nlen > 0 && isdirsep (newbuf[nlen - 1]))
 	newbuf[--nlen] = '\0';
@@ -1718,7 +1718,7 @@ rename (const char *oldpath, const char 
       set_errno (EROFS);
       goto out;
     }
-  if (new_dir_requested && !newpc.isdir ())
+  if (new_dir_requested && newpc.exists() && !newpc.isdir ())
     {
       set_errno (ENOTDIR);
       goto out;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]