diff options
| author | Alex Brainman <alex.brainman@gmail.com> | 2012-03-27 15:53:08 +1100 |
|---|---|---|
| committer | Alex Brainman <alex.brainman@gmail.com> | 2012-03-27 15:53:08 +1100 |
| commit | 7a3965417426e4405a6ec81ce486668fa5c36e36 (patch) | |
| tree | c878d62256237c8e6f48cf6df4eaf94a300fa6e6 /src/pkg/path/filepath | |
| parent | d6c9af6a4ec531369340e51cb008da514477ef17 (diff) | |
| download | go-7a3965417426e4405a6ec81ce486668fa5c36e36.tar.xz | |
path/filepath: use windows GetShortPathName api to force GetLongPathName to do its work
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/5928043
Diffstat (limited to 'src/pkg/path/filepath')
| -rw-r--r-- | src/pkg/path/filepath/symlink_windows.go | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/src/pkg/path/filepath/symlink_windows.go b/src/pkg/path/filepath/symlink_windows.go index 2d4257720e..2b5d1fc681 100644 --- a/src/pkg/path/filepath/symlink_windows.go +++ b/src/pkg/path/filepath/symlink_windows.go @@ -8,7 +8,24 @@ import ( "syscall" ) -func evalSymlinks(path string) (string, error) { +func toShort(path string) (string, error) { + p := syscall.StringToUTF16(path) + b := p // GetShortPathName says we can reuse buffer + n, err := syscall.GetShortPathName(&p[0], &b[0], uint32(len(b))) + if err != nil { + return "", err + } + if n > uint32(len(b)) { + b = make([]uint16, n) + n, err = syscall.GetShortPathName(&p[0], &b[0], uint32(len(b))) + if err != nil { + return "", err + } + } + return syscall.UTF16ToString(b), nil +} + +func toLong(path string) (string, error) { p := syscall.StringToUTF16(path) b := p // GetLongPathName says we can reuse buffer n, err := syscall.GetLongPathName(&p[0], &b[0], uint32(len(b))) @@ -23,13 +40,24 @@ func evalSymlinks(path string) (string, error) { } } b = b[:n] - s := syscall.UTF16ToString(b) + return syscall.UTF16ToString(b), nil +} + +func evalSymlinks(path string) (string, error) { + p, err := toShort(path) + if err != nil { + return "", err + } + p, err = toLong(p) + if err != nil { + return "", err + } // syscall.GetLongPathName does not change the case of the drive letter, // but the result of EvalSymlinks must be unique, so we have // EvalSymlinks(`c:\a`) == EvalSymlinks(`C:\a`). // Make drive letter upper case. This matches what os.Getwd returns. - if len(s) >= 2 && s[1] == ':' && 'a' <= s[0] && s[0] <= 'z' { - s = string(s[0]+'A'-'a') + s[1:] + if len(p) >= 2 && p[1] == ':' && 'a' <= p[0] && p[0] <= 'z' { + p = string(p[0]+'A'-'a') + p[1:] } - return Clean(s), nil + return Clean(p), nil } |
