From accb83b9baaf49cc8eba45c8d6d6cfab48562b32 Mon Sep 17 00:00:00 2001 From: ericb Date: Wed, 30 Sep 2009 02:11:04 +0000 Subject: [PATCH] * syscalls.cc (rename): Fix regression in rename("dir","d/"). --- winsup/cygwin/ChangeLog | 4 ++++ winsup/cygwin/syscalls.cc | 21 ++++++++++----------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 5eaa039bd9..3fb5232107 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,7 @@ +2009-09-29 Eric Blake + + * syscalls.cc (rename): Fix regression in rename("dir","d/"). + 2009-09-29 Corinna Vinschen * fhandler_socket.cc (fhandler_socket::recv_internal): Always call diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 67dddf3d98..1d160d3698 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; } -- 2.11.0