Daily bump.
[official-gcc.git] / libgo / go / os / types_windows.go
blob38901681e677fb8da535ecf026c94928513512d0
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 package os
7 import (
8 "sync"
9 "syscall"
10 "time"
13 // A fileStat is the implementation of FileInfo returned by Stat and Lstat.
14 type fileStat struct {
15 name string
16 sys syscall.Win32FileAttributeData
18 // used to implement SameFile
19 sync.Mutex
20 path string
21 vol uint32
22 idxhi uint32
23 idxlo uint32
26 func (fs *fileStat) Size() int64 {
27 return int64(fs.sys.FileSizeHigh)<<32 + int64(fs.sys.FileSizeLow)
30 func (fs *fileStat) Mode() (m FileMode) {
31 if fs == &devNullStat {
32 return ModeDevice | ModeCharDevice | 0666
34 if fs.sys.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
35 m |= ModeDir | 0111
37 if fs.sys.FileAttributes&syscall.FILE_ATTRIBUTE_READONLY != 0 {
38 m |= 0444
39 } else {
40 m |= 0666
42 return m
45 func (fs *fileStat) ModTime() time.Time {
46 return time.Unix(0, fs.sys.LastWriteTime.Nanoseconds())
49 // Sys returns syscall.Win32FileAttributeData for file fs.
50 func (fs *fileStat) Sys() interface{} { return &fs.sys }
52 func (fs *fileStat) loadFileId() error {
53 fs.Lock()
54 defer fs.Unlock()
55 if fs.path == "" {
56 // already done
57 return nil
59 pathp, err := syscall.UTF16PtrFromString(fs.path)
60 if err != nil {
61 return err
63 h, err := syscall.CreateFile(pathp, 0, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0)
64 if err != nil {
65 return err
67 defer syscall.CloseHandle(h)
68 var i syscall.ByHandleFileInformation
69 err = syscall.GetFileInformationByHandle(syscall.Handle(h), &i)
70 if err != nil {
71 return err
73 fs.path = ""
74 fs.vol = i.VolumeSerialNumber
75 fs.idxhi = i.FileIndexHigh
76 fs.idxlo = i.FileIndexLow
77 return nil
80 // devNullStat is fileStat structure describing DevNull file ("NUL").
81 var devNullStat = fileStat{
82 name: DevNull,
83 // hopefully this will work for SameFile
84 vol: 0,
85 idxhi: 0,
86 idxlo: 0,
89 func sameFile(fs1, fs2 *fileStat) bool {
90 e := fs1.loadFileId()
91 if e != nil {
92 return false
94 e = fs2.loadFileId()
95 if e != nil {
96 return false
98 return fs1.vol == fs2.vol && fs1.idxhi == fs2.idxhi && fs1.idxlo == fs2.idxlo
101 // For testing.
102 func atime(fi FileInfo) time.Time {
103 return time.Unix(0, fi.Sys().(*syscall.Win32FileAttributeData).LastAccessTime.Nanoseconds())