示例#1
0
文件: file_posix.go 项目: ds2dev/gcc
// 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
		}
	}
}
示例#2
0
// 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
}
示例#3
0
// 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
}
示例#4
0
// 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
		}
	}
}
示例#5
0
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
}
示例#6
0
文件: external.go 项目: tsandall/opa
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)}
}