mirror of
https://github.com/golang/go
synced 2024-11-17 02:54:45 -07:00
os: avoid GetFileInformationByHandleEx call when stat'ing files on Windows
os.Stat and os.Lstat on Windows use GetFileInformationByHandleEx to retrieve file information for reparse points and files that GetFileAttributesEx does not handle. However, GetFileInformationByHandleEx is only necessary for reparse points, so we can avoid the call for regular files. With this change we can drop the FAT hack that was added in CL 154377, as files won't have the FILE_ATTRIBUTE_REPARSE_POINT attribute set on that file system. Change-Id: Id18639067a6c3fa1bb2c6706d5b79358c224fe37 Reviewed-on: https://go-review.googlesource.com/c/go/+/566397 Reviewed-by: Carlos Amedee <carlos@golang.org> Reviewed-by: Alex Brainman <alex.brainman@gmail.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Bryan Mills <bcmills@google.com>
This commit is contained in:
parent
f7777688ca
commit
49319ed5c7
@ -48,18 +48,14 @@ func newFileStatFromGetFileInformationByHandle(path string, h syscall.Handle) (f
|
||||
return nil, &PathError{Op: "GetFileInformationByHandle", Path: path, Err: err}
|
||||
}
|
||||
|
||||
var ti windows.FILE_ATTRIBUTE_TAG_INFO
|
||||
err = windows.GetFileInformationByHandleEx(h, windows.FileAttributeTagInfo, (*byte)(unsafe.Pointer(&ti)), uint32(unsafe.Sizeof(ti)))
|
||||
if err != nil {
|
||||
if errno, ok := err.(syscall.Errno); ok && errno == windows.ERROR_INVALID_PARAMETER {
|
||||
// It appears calling GetFileInformationByHandleEx with
|
||||
// FILE_ATTRIBUTE_TAG_INFO fails on FAT file system with
|
||||
// ERROR_INVALID_PARAMETER. Clear ti.ReparseTag in that
|
||||
// instance to indicate no symlinks are possible.
|
||||
ti.ReparseTag = 0
|
||||
} else {
|
||||
var reparseTag uint32
|
||||
if d.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT != 0 {
|
||||
var ti windows.FILE_ATTRIBUTE_TAG_INFO
|
||||
err = windows.GetFileInformationByHandleEx(h, windows.FileAttributeTagInfo, (*byte)(unsafe.Pointer(&ti)), uint32(unsafe.Sizeof(ti)))
|
||||
if err != nil {
|
||||
return nil, &PathError{Op: "GetFileInformationByHandleEx", Path: path, Err: err}
|
||||
}
|
||||
reparseTag = ti.ReparseTag
|
||||
}
|
||||
|
||||
return &fileStat{
|
||||
@ -73,7 +69,7 @@ func newFileStatFromGetFileInformationByHandle(path string, h syscall.Handle) (f
|
||||
vol: d.VolumeSerialNumber,
|
||||
idxhi: d.FileIndexHigh,
|
||||
idxlo: d.FileIndexLow,
|
||||
ReparseTag: ti.ReparseTag,
|
||||
ReparseTag: reparseTag,
|
||||
// fileStat.path is used by os.SameFile to decide if it needs
|
||||
// to fetch vol, idxhi and idxlo. But these are already set,
|
||||
// so set fileStat.path to "" to prevent os.SameFile doing it again.
|
||||
|
Loading…
Reference in New Issue
Block a user