summaryrefslogtreecommitdiff
path: root/src/pkg/os/stat_windows.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/os/stat_windows.go')
-rw-r--r--src/pkg/os/stat_windows.go65
1 files changed, 40 insertions, 25 deletions
diff --git a/src/pkg/os/stat_windows.go b/src/pkg/os/stat_windows.go
index 2009d1f1b..e599583b2 100644
--- a/src/pkg/os/stat_windows.go
+++ b/src/pkg/os/stat_windows.go
@@ -5,13 +5,14 @@
package os
import (
- "unsafe"
"syscall"
+ "time"
+ "unsafe"
)
// Stat returns the FileInfo structure describing file.
// It returns the FileInfo and an error, if any.
-func (file *File) Stat() (fi *FileInfo, err Error) {
+func (file *File) Stat() (fi FileInfo, err error) {
if file == nil || file.fd < 0 {
return nil, EINVAL
}
@@ -21,10 +22,10 @@ func (file *File) Stat() (fi *FileInfo, err Error) {
}
var d syscall.ByHandleFileInformation
e := syscall.GetFileInformationByHandle(syscall.Handle(file.fd), &d)
- if e != 0 {
- return nil, &PathError{"GetFileInformationByHandle", file.name, Errno(e)}
+ if e != nil {
+ return nil, &PathError{"GetFileInformationByHandle", file.name, e}
}
- return setFileInfo(new(FileInfo), basename(file.name), d.FileAttributes, d.FileSizeHigh, d.FileSizeLow, d.CreationTime, d.LastAccessTime, d.LastWriteTime), nil
+ return toFileInfo(basename(file.name), d.FileAttributes, d.FileSizeHigh, d.FileSizeLow, d.CreationTime, d.LastAccessTime, d.LastWriteTime), nil
}
// Stat returns a FileInfo structure describing the named file and an error, if any.
@@ -32,22 +33,22 @@ func (file *File) Stat() (fi *FileInfo, err Error) {
// the file pointed at by the link and has fi.FollowedSymlink set to true.
// If name names an invalid symbolic link, the returned FileInfo describes
// the link itself and has fi.FollowedSymlink set to false.
-func Stat(name string) (fi *FileInfo, err Error) {
+func Stat(name string) (fi FileInfo, err error) {
if len(name) == 0 {
- return nil, &PathError{"Stat", name, Errno(syscall.ERROR_PATH_NOT_FOUND)}
+ return nil, &PathError{"Stat", name, syscall.Errno(syscall.ERROR_PATH_NOT_FOUND)}
}
var d syscall.Win32FileAttributeData
e := syscall.GetFileAttributesEx(syscall.StringToUTF16Ptr(name), syscall.GetFileExInfoStandard, (*byte)(unsafe.Pointer(&d)))
- if e != 0 {
- return nil, &PathError{"GetFileAttributesEx", name, Errno(e)}
+ if e != nil {
+ return nil, &PathError{"GetFileAttributesEx", name, e}
}
- return setFileInfo(new(FileInfo), basename(name), d.FileAttributes, d.FileSizeHigh, d.FileSizeLow, d.CreationTime, d.LastAccessTime, d.LastWriteTime), nil
+ return toFileInfo(basename(name), d.FileAttributes, d.FileSizeHigh, d.FileSizeLow, d.CreationTime, d.LastAccessTime, d.LastWriteTime), nil
}
// Lstat returns the FileInfo structure describing the named file and an
// error, if any. If the file is a symbolic link, the returned FileInfo
// describes the symbolic link. Lstat makes no attempt to follow the link.
-func Lstat(name string) (fi *FileInfo, err Error) {
+func Lstat(name string) (fi FileInfo, err error) {
// No links on Windows
return Stat(name)
}
@@ -76,23 +77,37 @@ func basename(name string) string {
return name
}
-func setFileInfo(fi *FileInfo, name string, fa, sizehi, sizelo uint32, ctime, atime, wtime syscall.Filetime) *FileInfo {
- fi.Mode = 0
+type winTimes struct {
+ atime, ctime syscall.Filetime
+}
+
+func toFileInfo(name string, fa, sizehi, sizelo uint32, ctime, atime, mtime syscall.Filetime) FileInfo {
+ fs := new(FileStat)
+ fs.mode = 0
if fa&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
- fi.Mode = fi.Mode | syscall.S_IFDIR
- } else {
- fi.Mode = fi.Mode | syscall.S_IFREG
+ fs.mode |= ModeDir
}
if fa&syscall.FILE_ATTRIBUTE_READONLY != 0 {
- fi.Mode = fi.Mode | 0444
+ fs.mode |= 0444
} else {
- fi.Mode = fi.Mode | 0666
+ fs.mode |= 0666
}
- fi.Size = int64(sizehi)<<32 + int64(sizelo)
- fi.Name = name
- fi.FollowedSymlink = false
- fi.Atime_ns = atime.Nanoseconds()
- fi.Mtime_ns = wtime.Nanoseconds()
- fi.Ctime_ns = ctime.Nanoseconds()
- return fi
+ fs.size = int64(sizehi)<<32 + int64(sizelo)
+ fs.name = name
+ fs.modTime = time.Unix(0, mtime.Nanoseconds())
+ fs.Sys = &winTimes{atime, ctime}
+ return fs
+}
+
+func sameFile(fs1, fs2 *FileStat) bool {
+ // TODO(rsc): Do better than this, but this matches what
+ // used to happen when code compared .Dev and .Ino,
+ // which were both always zero. Obviously not all files
+ // are the same.
+ return true
+}
+
+// For testing.
+func atime(fi FileInfo) time.Time {
+ return time.Unix(0, fi.(*FileStat).Sys.(*winTimes).atime.Nanoseconds())
}