]> Cypherpunks repositories - gostls13.git/commitdiff
os: rename only works as part of the same directory on Plan 9
authorDavid du Colombier <0intro@gmail.com>
Thu, 19 Dec 2013 20:20:03 +0000 (21:20 +0100)
committerDavid du Colombier <0intro@gmail.com>
Thu, 19 Dec 2013 20:20:03 +0000 (21:20 +0100)
R=golang-dev, lucio.dere, rsc
CC=golang-dev
https://golang.org/cl/44080046

src/pkg/os/file_plan9.go

index 278fae772cec71b698d41c92e8eb5d38e473e7c7..102ad5f8929ae315e1e1a6a89bed11fa4eff25a9 100644 (file)
@@ -6,6 +6,7 @@ package os
 
 import (
        "runtime"
+       "strings"
        "syscall"
        "time"
 )
@@ -314,6 +315,15 @@ func Remove(name string) error {
 }
 
 func rename(oldname, newname string) error {
+       dirname := oldname[:strings.LastIndex(oldname, "/")+1]
+       if strings.HasPrefix(newname, dirname) {
+               newname = newname[len(dirname):]
+       }
+
+       // If newname still contains slashes after removing the oldname
+       // prefix, the rename is cross-directory and must be rejected.
+       // This case is caught by d.Marshal below.
+
        var d syscall.Dir
 
        d.Null()
@@ -322,10 +332,10 @@ func rename(oldname, newname string) error {
        buf := make([]byte, syscall.STATFIXLEN+len(d.Name))
        n, err := d.Marshal(buf[:])
        if err != nil {
-               return &PathError{"rename", oldname, err}
+               return &LinkError{"rename", oldname, newname, err}
        }
        if err = syscall.Wstat(oldname, buf[:n]); err != nil {
-               return &PathError{"rename", oldname, err}
+               return &LinkError{"rename", oldname, newname, err}
        }
        return nil
 }