-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
/
Copy pathstat.jl
118 lines (100 loc) · 3.54 KB
/
stat.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
immutable Stat
device :: Uint
inode :: Uint
mode :: Uint
nlink :: Int
uid :: Uint
gid :: Uint
rdev :: Uint
size :: Int64
blksize :: Int64
blocks :: Int64
mtime :: Float64
ctime :: Float64
end
Stat(buf::Union(Vector{Uint8},Ptr{Uint8})) = Stat(
uint(ccall(:jl_stat_dev, Uint32, (Ptr{Uint8},), buf)),
uint(ccall(:jl_stat_ino, Uint32, (Ptr{Uint8},), buf)),
uint(ccall(:jl_stat_mode, Uint32, (Ptr{Uint8},), buf)),
int(ccall(:jl_stat_nlink, Uint32, (Ptr{Uint8},), buf)),
uint(ccall(:jl_stat_uid, Uint32, (Ptr{Uint8},), buf)),
uint(ccall(:jl_stat_gid, Uint32, (Ptr{Uint8},), buf)),
uint(ccall(:jl_stat_rdev, Uint32, (Ptr{Uint8},), buf)),
int64(ccall(:jl_stat_size, Uint64, (Ptr{Uint8},), buf)),
int64(ccall(:jl_stat_blksize, Uint64, (Ptr{Uint8},), buf)),
int64(ccall(:jl_stat_blocks, Uint64, (Ptr{Uint8},), buf)),
ccall(:jl_stat_mtime, Float64, (Ptr{Uint8},), buf),
ccall(:jl_stat_ctime, Float64, (Ptr{Uint8},), buf),
)
show(io::IO, st::Stat) = print("Stat(mode=$(oct(st.mode,6)), size=$(st.size))")
# stat & lstat functions
const stat_buf = Array(Uint8, ccall(:jl_sizeof_stat, Int32, ()))
macro stat_call(sym,arg1type,arg)
quote
fill!(stat_buf,0)
r = ccall($(Expr(:quote,sym)), Int32, ($arg1type,Ptr{Uint8}), $arg, stat_buf)
r==0 || r==UV_ENOENT || r==UV_ENOTDIR || throw(UVError("stat",r))
st = Stat(stat_buf)
if ispath(st) != (r==0)
error("WTF: stat returned zero type for a valid path!?")
end
st
end
end
stat(fd::RawFD) = @stat_call jl_fstat Int32 fd.fd
stat(fd::Integer) = @stat_call jl_fstat Int32 fd
stat(path::ByteString) = @stat_call jl_stat Ptr{Uint8} path
stat(path::String) = stat(bytestring(path))
lstat(path::ByteString) = @stat_call jl_lstat Ptr{Uint8} path
lstat(path::String) = lstat(bytestring(path))
stat(path...) = stat(joinpath(path...))
lstat(path...) = lstat(joinpath(path...))
# mode type predicates
ispath(st::Stat) = st.mode & 0xf000 != 0x0000
isfifo(st::Stat) = st.mode & 0xf000 == 0x1000
ischardev(st::Stat) = st.mode & 0xf000 == 0x2000
isdir(st::Stat) = st.mode & 0xf000 == 0x4000
isblockdev(st::Stat) = st.mode & 0xf000 == 0x6000
isfile(st::Stat) = st.mode & 0xf000 == 0x8000
islink(st::Stat) = st.mode & 0xf000 == 0xa000
issocket(st::Stat) = st.mode & 0xf000 == 0xc000
# mode permission predicates
issetuid(st::Stat) = (st.mode & 0o4000) > 0
issetgid(st::Stat) = (st.mode & 0o2000) > 0
issticky(st::Stat) = (st.mode & 0o1000) > 0
isreadable(st::Stat) = (st.mode & 0o444) > 0
iswritable(st::Stat) = (st.mode & 0o222) > 0
isexecutable(st::Stat) = (st.mode & 0o111) > 0
uperm(st::Stat) = uint8(st.mode >> 6) & 0x7
gperm(st::Stat) = uint8(st.mode >> 3) & 0x7
operm(st::Stat) = uint8(st.mode ) & 0x7
# mode predicate methods for file names
for f in {
:ispath
:isfifo
:ischardev
:isdir
:isblockdev
:isfile
:islink
:issocket
:issetuid
:issetgid
:issticky
:isreadable
:iswritable
:isexecutable
:uperm
:gperm
:operm
}
@eval ($f)(path...) = ($f)(stat(path...))
end
islink(path...) = islink(lstat(path...))
# some convenience functions
filemode(path...) = stat(path...).mode
filesize(path...) = stat(path...).size
mtime(path...) = stat(path...).mtime
ctime(path...) = stat(path...).ctime
samefile(a::Stat, b::Stat) = a.device==b.device && a.inode==b.inode
samefile(a::String, b::String) = samefile(stat(a),stat(b))