Commit 9e0e9ac5 authored by LE Manh Cuong's avatar LE Manh Cuong Committed by Alex Brainman

os: fix windows Lstat missing name for some files

On Windows, GetFileAttributesEx fails with ERROR_SHARING_VIOLATION for
some files, like c:\pagefile.sys. In this case,
newFileStatFromWin32finddata is used to fill file info, but it does not fill
name and path.

After getting file stat from newFileStatFromWin32finddata, just set file info
name and path before return fixes the issue.

Fixes #30883

Change-Id: I654e96c634e8a9bf5ce7e1aaa93968e88953620d
Reviewed-on: https://go-review.googlesource.com/c/go/+/167779
Run-TryBot: Alex Brainman <alex.brainman@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarAlex Brainman <alex.brainman@gmail.com>
parent e0181ff5
......@@ -755,8 +755,11 @@ func TestReadStdin(t *testing.T) {
}
func TestStatPagefile(t *testing.T) {
_, err := os.Stat(`c:\pagefile.sys`)
fi, err := os.Stat(`c:\pagefile.sys`)
if err == nil {
if fi.Name() == "" {
t.Fatal(`FileInfo of c:\pagefile.sys has empty name`)
}
return
}
if os.IsNotExist(err) {
......
......@@ -80,7 +80,6 @@ func stat(funcname, name string, createFileAttrs uint32) (FileInfo, error) {
if err == nil && fa.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT == 0 {
// Not a symlink.
fs := &fileStat{
path: name,
FileAttributes: fa.FileAttributes,
CreationTime: fa.CreationTime,
LastAccessTime: fa.LastAccessTime,
......@@ -88,14 +87,9 @@ func stat(funcname, name string, createFileAttrs uint32) (FileInfo, error) {
FileSizeHigh: fa.FileSizeHigh,
FileSizeLow: fa.FileSizeLow,
}
// Gather full path to be used by os.SameFile later.
if !isAbs(fs.path) {
fs.path, err = syscall.FullPath(fs.path)
if err != nil {
return nil, &PathError{"FullPath", name, err}
}
if err := fs.saveInfoFromPath(name); err != nil {
return nil, err
}
fs.name = basename(name)
return fs, nil
}
// GetFileAttributesEx fails with ERROR_SHARING_VIOLATION error for
......@@ -107,7 +101,11 @@ func stat(funcname, name string, createFileAttrs uint32) (FileInfo, error) {
return nil, &PathError{"FindFirstFile", name, err}
}
syscall.FindClose(sh)
return newFileStatFromWin32finddata(&fd), nil
fs := newFileStatFromWin32finddata(&fd)
if err := fs.saveInfoFromPath(name); err != nil {
return nil, err
}
return fs, nil
}
// Finally use CreateFile.
......
......@@ -189,6 +189,21 @@ func (fs *fileStat) loadFileId() error {
return nil
}
// saveInfoFromPath saves full path of the file to be used by os.SameFile later,
// and set name from path.
func (fs *fileStat) saveInfoFromPath(path string) error {
fs.path = path
if !isAbs(fs.path) {
var err error
fs.path, err = syscall.FullPath(fs.path)
if err != nil {
return &PathError{"FullPath", path, err}
}
}
fs.name = basename(path)
return nil
}
// devNullStat is fileStat structure describing DevNull file ("NUL").
var devNullStat = fileStat{
name: DevNull,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment