diff options
Diffstat (limited to 'src/pkg/os/stat_windows.go')
-rw-r--r-- | src/pkg/os/stat_windows.go | 65 |
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()) } |