]> Cypherpunks repositories - gostls13.git/commitdiff
os: fix windows Lstat missing name for some files
authorLE Manh Cuong <cuong.manhle.vn@gmail.com>
Sun, 17 Mar 2019 04:56:29 +0000 (11:56 +0700)
committerAlex Brainman <alex.brainman@gmail.com>
Wed, 20 Mar 2019 08:35:29 +0000 (08:35 +0000)
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: Alex Brainman <alex.brainman@gmail.com>
src/os/os_windows_test.go
src/os/stat_windows.go
src/os/types_windows.go

index 0b42e089bd10ff76a547579119885ccea1b738ff..326670cc9da2d8131a1c666b05456c0d92f84cd4 100644 (file)
@@ -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) {
index 271ff5f8434270622baca85b236997dfa96d5f16..fd22ef21ab312b79ed675fa54321d09cdb7c55b8 100644 (file)
@@ -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.
index 5e33292bec68197771b515c695eafec4386630cb..3d1a6674b145881014d1b7a07cb41fe9935a3ea7 100644 (file)
@@ -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,