]> Cypherpunks repositories - gostls13.git/commitdiff
os: lstat oldname before renaming
authorAlexander Menzhinsky <amenzhinsky@gmail.com>
Thu, 13 Apr 2017 16:23:35 +0000 (11:23 -0500)
committerBrad Fitzpatrick <bradfitz@golang.org>
Thu, 18 May 2017 22:40:35 +0000 (22:40 +0000)
Fixes #19647

Change-Id: Ife4f98cf2c55ee9490843797213dae2f2647b0a3
Reviewed-on: https://go-review.googlesource.com/40577
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/os/file_unix.go
src/os/os_test.go

index 86271d53e897d1b6bc4618419340a64c0bbe064e..f790b6e910dd75ecdf15278a9b29bbd4131ed5ca 100644 (file)
@@ -20,11 +20,20 @@ func fixLongPath(path string) string {
 func rename(oldname, newname string) error {
        fi, err := Lstat(newname)
        if err == nil && fi.IsDir() {
+               // if we cannot stat oldname we should
+               // return that error in favor of EEXIST
+               fi, err = Lstat(oldname)
+               if err != nil {
+                       if pErr, ok := err.(*PathError); ok {
+                               err = pErr.Err
+                       }
+                       return &LinkError{"rename", oldname, newname, err}
+               }
                return &LinkError{"rename", oldname, newname, syscall.EEXIST}
        }
-       e := syscall.Rename(oldname, newname)
-       if e != nil {
-               return &LinkError{"rename", oldname, newname, e}
+       err = syscall.Rename(oldname, newname)
+       if err != nil {
+               return &LinkError{"rename", oldname, newname, err}
        }
        return nil
 }
index 8e2cd14ddf1b48c29c6b94c3fbf01a227971bcfb..22777aef9f7723c85399955c91c68230a4cda2ab 100644 (file)
@@ -886,6 +886,18 @@ func TestRenameFailed(t *testing.T) {
        }
 }
 
+func TestRenameNotExisting(t *testing.T) {
+       defer chtmpdir(t)()
+       from, to := "doesnt-exist", "dest"
+
+       Mkdir(to, 0777)
+       defer Remove(to)
+
+       if err := Rename(from, to); !IsNotExist(err) {
+               t.Errorf("Rename(%q, %q) = %v; want an IsNotExist error", from, to, err)
+       }
+}
+
 func TestRenameToDirFailed(t *testing.T) {
        defer chtmpdir(t)()
        from, to := "renamefrom", "renameto"