1 // Copyright 2011 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.
12 func sameFile(fs1
, fs2
*fileStat
) bool {
13 a
:= fs1
.sys
.(*syscall
.Dir
)
14 b
:= fs2
.sys
.(*syscall
.Dir
)
15 return a
.Qid
.Path
== b
.Qid
.Path
&& a
.Type
== b
.Type
&& a
.Dev
== b
.Dev
18 func fileInfoFromStat(d
*syscall
.Dir
) FileInfo
{
21 size
: int64(d
.Length
),
22 modTime
: time
.Unix(int64(d
.Mtime
), 0),
25 fs
.mode
= FileMode(d
.Mode
& 0777)
26 if d
.Mode
&syscall
.DMDIR
!= 0 {
29 if d
.Mode
&syscall
.DMAPPEND
!= 0 {
32 if d
.Mode
&syscall
.DMEXCL
!= 0 {
33 fs
.mode |
= ModeExclusive
35 if d
.Mode
&syscall
.DMTMP
!= 0 {
36 fs
.mode |
= ModeTemporary
41 // arg is an open *File or a path string.
42 func dirstat(arg
interface{}) (*syscall
.Dir
, error
) {
45 // This is big enough for most stat messages
46 // and rounded to a multiple of 128 bytes.
47 size
:= (syscall
.STATFIXLEN
+ 16*4 + 128) &^ 128
49 for i
:= 0; i
< 2; i
++ {
50 buf
:= make([]byte, size
)
54 switch a
:= arg
.(type) {
57 n
, err
= syscall
.Fstat(a
.fd
, buf
)
60 n
, err
= syscall
.Stat(a
, buf
)
62 panic("phase error in dirstat")
65 return nil, &PathError
{"stat", name
, err
}
67 if n
< syscall
.STATFIXLEN
{
68 return nil, &PathError
{"stat", name
, syscall
.ErrShortStat
}
71 // Pull the real size out of the stat message.
72 size
= int(uint16(buf
[0]) |
uint16(buf
[1])<<8)
74 // If the stat message is larger than our buffer we will
75 // go around the loop and allocate one that is big enough.
80 d
, err
:= syscall
.UnmarshalDir(buf
[:n
])
82 return nil, &PathError
{"stat", name
, err
}
86 return nil, &PathError
{"stat", name
, syscall
.ErrBadStat
}
89 // Stat returns a FileInfo describing the named file.
90 // If there is an error, it will be of type *PathError.
91 func Stat(name
string) (fi FileInfo
, err error
) {
92 d
, err
:= dirstat(name
)
96 return fileInfoFromStat(d
), nil
99 // Lstat returns a FileInfo describing the named file.
100 // If the file is a symbolic link, the returned FileInfo
101 // describes the symbolic link. Lstat makes no attempt to follow the link.
102 // If there is an error, it will be of type *PathError.
103 func Lstat(name
string) (fi FileInfo
, err error
) {
108 func atime(fi FileInfo
) time
.Time
{
109 return time
.Unix(int64(fi
.Sys().(*syscall
.Dir
).Atime
), 0)