os: factor out newFileStatFromWin32FileAttributeData

The stat function is quite long on Windows. Simplify it a bit by
factoring out the creation of a fileStat from a Win32FileAttributeData.

This also makes it more consistent with the creation of fileStats
from other sources, which all have their own dedicated functions.

Change-Id: I0443f96d892b70ce7f3b5e92c5049e4e4a240c6c
Reviewed-on: https://go-review.googlesource.com/c/go/+/566435
Reviewed-by: Carlos Amedee <carlos@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
qmuntal 2024-02-23 15:04:22 +01:00 committed by Quim Muntal
parent 88b2f25005
commit ec8833ecc1
2 changed files with 22 additions and 17 deletions

View File

@ -33,6 +33,15 @@ func stat(funcname, name string, followSurrogates bool) (FileInfo, error) {
// See https://golang.org/issues/19922#issuecomment-300031421 for details.
var fa syscall.Win32FileAttributeData
err = syscall.GetFileAttributesEx(namep, syscall.GetFileExInfoStandard, (*byte)(unsafe.Pointer(&fa)))
if err == nil && fa.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT == 0 {
// Not a surrogate for another named entity, because it isn't any kind of reparse point.
// The information we got from GetFileAttributesEx is good enough for now.
fs := newFileStatFromWin32FileAttributeData(&fa)
if err := fs.saveInfoFromPath(name); err != nil {
return nil, err
}
return fs, nil
}
// GetFileAttributesEx fails with ERROR_SHARING_VIOLATION error for
// files like c:\pagefile.sys. Use FindFirstFile for such files.
@ -53,23 +62,6 @@ func stat(funcname, name string, followSurrogates bool) (FileInfo, error) {
}
}
if err == nil && fa.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT == 0 {
// Not a surrogate for another named entity, because it isn't any kind of reparse point.
// The information we got from GetFileAttributesEx is good enough for now.
fs := &fileStat{
FileAttributes: fa.FileAttributes,
CreationTime: fa.CreationTime,
LastAccessTime: fa.LastAccessTime,
LastWriteTime: fa.LastWriteTime,
FileSizeHigh: fa.FileSizeHigh,
FileSizeLow: fa.FileSizeLow,
}
if err := fs.saveInfoFromPath(name); err != nil {
return nil, err
}
return fs, nil
}
// Use CreateFile to determine whether the file is a name surrogate and, if so,
// save information about the link target.
// Set FILE_FLAG_BACKUP_SEMANTICS so that CreateFile will create the handle

View File

@ -76,6 +76,19 @@ func newFileStatFromGetFileInformationByHandle(path string, h syscall.Handle) (f
}, nil
}
// newFileStatFromWin32FileAttributeData copies all required information
// from syscall.Win32FileAttributeData d into the newly created fileStat.
func newFileStatFromWin32FileAttributeData(d *syscall.Win32FileAttributeData) *fileStat {
return &fileStat{
FileAttributes: d.FileAttributes,
CreationTime: d.CreationTime,
LastAccessTime: d.LastAccessTime,
LastWriteTime: d.LastWriteTime,
FileSizeHigh: d.FileSizeHigh,
FileSizeLow: d.FileSizeLow,
}
}
// newFileStatFromFileIDBothDirInfo copies all required information
// from windows.FILE_ID_BOTH_DIR_INFO d into the newly created fileStat.
func newFileStatFromFileIDBothDirInfo(d *windows.FILE_ID_BOTH_DIR_INFO) *fileStat {