// Readlink returns the destination of the named symbolic link. // If there is an error, it will be of type *PathError. func Readlink(name string) (string, error) { for len := 128; ; len *= 2 { b := make([]byte, len) n, e := syscall.Readlink(name, b) if e != nil { return "", &PathError{"readlink", name, e} } if n < len { return string(b[0:n]), nil } } }
// Readlink reads the contents of a symbolic link: the destination of // the link. It returns the contents and an Error, if any. func Readlink(name string) (string, Error) { for len := 128; ; len *= 2 { b := make([]byte, len) n, e := syscall.Readlink(name, b) if e != 0 { return "", &PathError{"readlink", name, Errno(e)} } if n < len { return string(b[0:n]), nil } } // Silence 6g. return "", nil }
// GetFdName returns file name for given descriptor. func GetFdName(fd uintptr) (name string, err error) { path := fmt.Sprintf("/proc/self/fd/%d", int(fd)) var ( fi os.FileInfo n int ) if fi, err = os.Lstat(path); err != nil { return } buf := make([]byte, fi.Size()+1) if n, err = syscall.Readlink(path, buf); err == nil { name = string(buf[:n]) } return }
// Readlink returns the file pointed to by the given soft link, or an error of // type PathError otherwise. This mimics the os.Readlink() function, but works // around a bug we've seen in CentOS 5.10 (kernel 2.6.27.10 on x86_64) where the // underlying OS function readlink() returns a wrong number of bytes for the // result (see man readlink). Here we don't rely blindly on that value; if // there's a zero byte among that number of bytes, then we keep only up to that // point. // // NOTE: We chose not to use os.Readlink() and then search on its result to // avoid an extra overhead of converting back to []byte. The function to search // for a byte over the string itself (strings.IndexByte()) is only available // starting with Go 1.2. Also, we're not searching at every iteration to save // some CPU time, even though that could mean extra iterations for systems // affected with this bug. But it's wiser to optimize for the general case // (i.e., those not affected). func Readlink(name string) (string, error) { for len := 128; ; len *= 2 { b := make([]byte, len) n, e := syscall.Readlink(name, b) if e != nil { return "", &os.PathError{"readlink", name, e} } if n < len { if z := bytes.IndexByte(b[:n], 0); z >= 0 { n = z } return string(b[:n]), nil } } }
func open(_relative *cursor, _relativePath string) (*cursor, Error) { var _path string if _relative != nil { _path = path.Join(_relative.entity.Path, _relativePath) } else { _path = _relativePath } var _descriptor, _errno int var _stat syscall.Stat_t var _link string _descriptor = -1 _errno = syscall.Lstat(_path, &_stat) if _errno == 0 { var _flags int = syscall.O_NOCTTY | syscall.O_NOFOLLOW | syscall.O_CLOEXEC | syscall.O_LARGEFILE | syscall.O_NOATIME var _mode uint32 = syscall.O_RDONLY for { if ((_stat.Mode & syscall.S_IFMT) != syscall.S_IFREG) && ((_stat.Mode & syscall.S_IFMT) != syscall.S_IFDIR) { break } if _relative != nil { _descriptor, _errno = syscall.Openat(_relative.entity.Descriptor, _relativePath, _flags, _mode) } else { _descriptor, _errno = syscall.Open(_relativePath, _flags, _mode) } if (_errno == syscall.EPERM) && ((_flags & syscall.O_NOATIME) == syscall.O_NOATIME) { _flags &= ^syscall.O_NOATIME continue } else { break } } switch { case _errno == 0: _errno = syscall.Fstat(_descriptor, &_stat) case _errno == syscall.EACCES: _descriptor = -1 case _errno == syscall.ELOOP: _descriptor = -1 case _errno == syscall.ENOENT: return nil, newError("open", _path, -1, _errno) case _errno != 0: _descriptor = -1 } if (_errno == 0) && ((_stat.Mode & syscall.S_IFMT) == syscall.S_IFLNK) { var _linkBuffer [syscall.PathMax + 1]byte var _linkLimit int _linkLimit, _errno = syscall.Readlink(_path, _linkBuffer[:]) if _errno == 0 { _link = string(_linkBuffer[:_linkLimit]) } } if (_errno != 0) && (_descriptor >= 0) { syscall.Close(_descriptor) _descriptor = -1 } } _entity := new(Entity) _entity.Name = path.Base(_path) _entity.Path = _path _entity.Errno = _errno _entity.Stat = _stat _entity.Link = _link _entity.Descriptor = _descriptor _cursor := new(cursor) _cursor.parent = _relative _cursor.entity = _entity return _cursor, nil }
func ext۰syscall۰Readlink(fr *frame, args []value) value { path := args[0].(string) buf := valueToBytes(args[1]) n, err := syscall.Readlink(path, buf) return tuple{n, wrapError(err)} }