summaryrefslogtreecommitdiff
path: root/libgo/go/path/filepath/symlink_windows.go
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2012-04-03 11:15:51 -0700
committerH.J. Lu <hjl.tools@gmail.com>2012-04-03 11:15:51 -0700
commitc924cab2fd8932bdfb107c4ca7d26128ba56f19e (patch)
tree0eea6430e211564fc331f66625373ec761837982 /libgo/go/path/filepath/symlink_windows.go
parent4c15f6d5728cb694d7d954b2c20409fdc0400b9e (diff)
parent3cef948a814542119083003a3c35a24e036230b6 (diff)
downloadgcc-c924cab2fd8932bdfb107c4ca7d26128ba56f19e.tar.gz
Merge remote-tracking branch 'origin/master' into hjl/x32/addr32hjl/x32/addr32
Diffstat (limited to 'libgo/go/path/filepath/symlink_windows.go')
-rw-r--r--libgo/go/path/filepath/symlink_windows.go63
1 files changed, 63 insertions, 0 deletions
diff --git a/libgo/go/path/filepath/symlink_windows.go b/libgo/go/path/filepath/symlink_windows.go
new file mode 100644
index 00000000000..1ee939928e9
--- /dev/null
+++ b/libgo/go/path/filepath/symlink_windows.go
@@ -0,0 +1,63 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package filepath
+
+import (
+ "syscall"
+)
+
+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)))
+ if err != nil {
+ return "", err
+ }
+ if n > uint32(len(b)) {
+ b = make([]uint16, n)
+ n, err = syscall.GetLongPathName(&p[0], &b[0], uint32(len(b)))
+ if err != nil {
+ return "", err
+ }
+ }
+ b = b[:n]
+ 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.
+ if len(p) >= 2 && p[1] == ':' && 'a' <= p[0] && p[0] <= 'z' {
+ p = string(p[0]+'A'-'a') + p[1:]
+ }
+ return Clean(p), nil
+}