summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Blake <eblake@redhat.com>2009-09-30 02:11:05 +0000
committerEric Blake <eblake@redhat.com>2009-09-30 02:11:05 +0000
commit1c0909882cc36a5aaca28b56edc9c19227805d8e (patch)
tree3dcb8225e6bfbcc703a41af992ba4417e5124d80
parente634d38754276af9b9474e2030d6d4355c570b2a (diff)
downloadcygnal-1c0909882cc36a5aaca28b56edc9c19227805d8e.tar.gz
cygnal-1c0909882cc36a5aaca28b56edc9c19227805d8e.tar.bz2
cygnal-1c0909882cc36a5aaca28b56edc9c19227805d8e.zip
* syscalls.cc (rename): Fix regression in rename("dir","d/").
-rw-r--r--winsup/cygwin/ChangeLog4
-rw-r--r--winsup/cygwin/syscalls.cc21
2 files changed, 14 insertions, 11 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 5eaa039bd..3fb523210 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,7 @@
+2009-09-29 Eric Blake <ebb9@byu.net>
+
+ * syscalls.cc (rename): Fix regression in rename("dir","d/").
+
2009-09-29 Corinna Vinschen <corinna@vinschen.de>
* fhandler_socket.cc (fhandler_socket::recv_internal): Always call
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 67dddf3d9..1d160d369 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -1668,17 +1668,20 @@ rename (const char *oldpath, const char *newpath)
if (!*oldpath || !*newpath)
{
+ /* Reject rename("","x"), rename("x",""). */
set_errno (ENOENT);
goto out;
}
if (has_dot_last_component (oldpath, true))
{
+ /* Reject rename("dir/.","x"). */
oldpc.check (oldpath, PC_SYM_NOFOLLOW, stat_suffixes);
set_errno (oldpc.isdir () ? EINVAL : ENOTDIR);
goto out;
}
if (has_dot_last_component (newpath, true))
{
+ /* Reject rename("dir","x/."). */
newpc.check (newpath, PC_SYM_NOFOLLOW, stat_suffixes);
set_errno (!newpc.exists () ? ENOENT : newpc.isdir () ? EINVAL : ENOTDIR);
goto out;
@@ -1724,6 +1727,7 @@ rename (const char *oldpath, const char *newpath)
}
if (old_dir_requested && !oldpc.isdir ())
{
+ /* Reject rename("file/","x"). */
set_errno (ENOTDIR);
goto out;
}
@@ -1759,21 +1763,16 @@ rename (const char *oldpath, const char *newpath)
set_errno (EROFS);
goto out;
}
- if (new_dir_requested)
+ if (new_dir_requested && !(newpc.exists ()
+ ? newpc.isdir () : oldpc.isdir ()))
{
- if (!newpc.exists())
- {
- set_errno (ENOENT);
- goto out;
- }
- if (!newpc.isdir ())
- {
- set_errno (ENOTDIR);
- goto out;
- }
+ /* Reject rename("file1","file2/"), but allow rename("dir","d/"). */
+ set_errno (newpc.exists () ? ENOTDIR : ENOENT);
+ goto out;
}
if (newpc.exists () && (oldpc.isdir () ? !newpc.isdir () : newpc.isdir ()))
{
+ /* Reject rename("file","dir") and rename("dir","file"). */
set_errno (newpc.isdir () ? EISDIR : ENOTDIR);
goto out;
}