]> Cypherpunks repositories - gostls13.git/commitdiff
os: reject Rename("old", "new") where new is a directory
authorRuss Cox <rsc@golang.org>
Tue, 18 Oct 2016 16:34:19 +0000 (12:34 -0400)
committerRuss Cox <rsc@golang.org>
Wed, 19 Oct 2016 01:21:05 +0000 (01:21 +0000)
Unix rejects this when new is a non-empty directory.
Other systems reject this when new is a directory, empty or not.
Make Unix reject empty directory too.

Fixes #14527.

Change-Id: Ice24b8065264c91c22cba24aa73e142386c29c87
Reviewed-on: https://go-review.googlesource.com/31358
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/os/file_unix.go
src/os/os_test.go

index 83a814348fb539c8756b07b053bce67d6c482e05..0d0167f9e3fa2b71ccfa591af6d369a4f9fb8279 100644 (file)
@@ -12,6 +12,10 @@ import (
 )
 
 func rename(oldname, newname string) error {
+       fi, err := Lstat(newname)
+       if err == nil && fi.IsDir() {
+               return &LinkError{"rename", oldname, newname, syscall.EEXIST}
+       }
        e := syscall.Rename(oldname, newname)
        if e != nil {
                return &LinkError{"rename", oldname, newname, e}
index 0c4042a4bf3b8ff04c462ee7629388823c0cab9c..44a578418f230e69d1ab399fbaf70e3d7a75f6ba 100644 (file)
@@ -828,6 +828,37 @@ func TestRenameFailed(t *testing.T) {
        }
 }
 
+func TestRenameToDirFailed(t *testing.T) {
+       defer chtmpdir(t)()
+       from, to := "renamefrom", "renameto"
+
+       Remove(from)
+       Remove(to)
+       Mkdir(from, 0777)
+       Mkdir(to, 0777)
+
+       err := Rename(from, to)
+       switch err := err.(type) {
+       case *LinkError:
+               if err.Op != "rename" {
+                       t.Errorf("rename %q, %q: err.Op: want %q, got %q", from, to, "rename", err.Op)
+               }
+               if err.Old != from {
+                       t.Errorf("rename %q, %q: err.Old: want %q, got %q", from, to, from, err.Old)
+               }
+               if err.New != to {
+                       t.Errorf("rename %q, %q: err.New: want %q, got %q", from, to, to, err.New)
+               }
+       case nil:
+               t.Errorf("rename %q, %q: expected error, got nil", from, to)
+
+               // cleanup whatever was placed in "renameto"
+               Remove(to)
+       default:
+               t.Errorf("rename %q, %q: expected %T, got %T %v", from, to, new(LinkError), err, err)
+       }
+}
+
 func exec(t *testing.T, dir, cmd string, args []string, expect string) {
        r, w, err := Pipe()
        if err != nil {