mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
os: make Readlink work with symlinks with target like \??\Volume{ABCD}\
windows-arm TMP directory live inside such link (see https://github.com/golang/go/issues/29746#issuecomment-456526811 for details), so symlinks like that will be common at least on windows-arm. This CL builds on current syscall.Readlink implementation. Main difference between the two is how new code handles symlink targets, like \??\Volume{ABCD}\. New implementation uses Windows CreateFile API with FILE_FLAG_OPEN_REPARSE_POINT flag to get \??\Volume{ABCD}\ file handle. And then it uses Windows GetFinalPathNameByHandle with VOLUME_NAME_DOS flag to convert that handle into standard Windows path. FILE_FLAG_OPEN_REPARSE_POINT flag ensures that symlink is not followed when CreateFile opens the file. Fixes #30463 Change-Id: I33b18227ce36144caed694169ef2e429fd995fb4 Reviewed-on: https://go-review.googlesource.com/c/164201 Run-TryBot: Alex Brainman <alex.brainman@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
e27402aee0
commit
2edd559223
5 changed files with 278 additions and 20 deletions
|
|
@ -399,3 +399,22 @@ func (f *File) readdir(n int) (fi []FileInfo, err error) {
|
|||
}
|
||||
return fi, err
|
||||
}
|
||||
|
||||
// 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 := fixCount(syscall.Readlink(name, b))
|
||||
// buffer too small
|
||||
if runtime.GOOS == "aix" && e == syscall.ERANGE {
|
||||
continue
|
||||
}
|
||||
if e != nil {
|
||||
return "", &PathError{"readlink", name, e}
|
||||
}
|
||||
if n < len {
|
||||
return string(b[0:n]), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue