summaryrefslogtreecommitdiff
path: root/libgo/go/path/filepath/symlink.go
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2012-03-30 21:27:11 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2012-03-30 21:27:11 +0000
commit29f40c0d4065a0f30bbd1d4c4c45e742d42cffb0 (patch)
tree9a0dfa827abe382ac0f44768e5365b87f00ac0a9 /libgo/go/path/filepath/symlink.go
parent9731acf5058127b5cd40d79134497c798f9188a1 (diff)
downloadgcc-29f40c0d4065a0f30bbd1d4c4c45e742d42cffb0.tar.gz
libgo: Update to weekly.2012-03-13.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@186023 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo/go/path/filepath/symlink.go')
-rw-r--r--libgo/go/path/filepath/symlink.go67
1 files changed, 67 insertions, 0 deletions
diff --git a/libgo/go/path/filepath/symlink.go b/libgo/go/path/filepath/symlink.go
new file mode 100644
index 00000000000..307dd0f8fee
--- /dev/null
+++ b/libgo/go/path/filepath/symlink.go
@@ -0,0 +1,67 @@
+// 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.
+
+// +build !windows
+
+package filepath
+
+import (
+ "bytes"
+ "errors"
+ "os"
+ "strings"
+)
+
+func evalSymlinks(path string) (string, error) {
+ const maxIter = 255
+ originalPath := path
+ // consume path by taking each frontmost path element,
+ // expanding it if it's a symlink, and appending it to b
+ var b bytes.Buffer
+ for n := 0; path != ""; n++ {
+ if n > maxIter {
+ return "", errors.New("EvalSymlinks: too many links in " + originalPath)
+ }
+
+ // find next path component, p
+ i := strings.IndexRune(path, Separator)
+ var p string
+ if i == -1 {
+ p, path = path, ""
+ } else {
+ p, path = path[:i], path[i+1:]
+ }
+
+ if p == "" {
+ if b.Len() == 0 {
+ // must be absolute path
+ b.WriteRune(Separator)
+ }
+ continue
+ }
+
+ fi, err := os.Lstat(b.String() + p)
+ if err != nil {
+ return "", err
+ }
+ if fi.Mode()&os.ModeSymlink == 0 {
+ b.WriteString(p)
+ if path != "" {
+ b.WriteRune(Separator)
+ }
+ continue
+ }
+
+ // it's a symlink, put it at the front of path
+ dest, err := os.Readlink(b.String() + p)
+ if err != nil {
+ return "", err
+ }
+ if IsAbs(dest) {
+ b.Reset()
+ }
+ path = dest + string(Separator) + path
+ }
+ return Clean(b.String()), nil
+}