github.com/spotify/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/pkg/path/filepath/symlink.go (about) 1 // Copyright 2012 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build !windows 6 7 package filepath 8 9 import ( 10 "bytes" 11 "errors" 12 "os" 13 "strings" 14 ) 15 16 func evalSymlinks(path string) (string, error) { 17 const maxIter = 255 18 originalPath := path 19 // consume path by taking each frontmost path element, 20 // expanding it if it's a symlink, and appending it to b 21 var b bytes.Buffer 22 for n := 0; path != ""; n++ { 23 if n > maxIter { 24 return "", errors.New("EvalSymlinks: too many links in " + originalPath) 25 } 26 27 // find next path component, p 28 i := strings.IndexRune(path, Separator) 29 var p string 30 if i == -1 { 31 p, path = path, "" 32 } else { 33 p, path = path[:i], path[i+1:] 34 } 35 36 if p == "" { 37 if b.Len() == 0 { 38 // must be absolute path 39 b.WriteRune(Separator) 40 } 41 continue 42 } 43 44 fi, err := os.Lstat(b.String() + p) 45 if err != nil { 46 return "", err 47 } 48 if fi.Mode()&os.ModeSymlink == 0 { 49 b.WriteString(p) 50 if path != "" { 51 b.WriteRune(Separator) 52 } 53 continue 54 } 55 56 // it's a symlink, put it at the front of path 57 dest, err := os.Readlink(b.String() + p) 58 if err != nil { 59 return "", err 60 } 61 if IsAbs(dest) { 62 b.Reset() 63 } 64 path = dest + string(Separator) + path 65 } 66 return Clean(b.String()), nil 67 }