github.com/rohankumardubey/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  }