@@ -63,6 +63,7 @@ struct StatStruct
6363 blocks :: Int64
6464 mtime :: Float64
6565 ctime :: Float64
66+ ioerrno :: Int32
6667end
6768
6869@eval function Base.:(== )(x:: StatStruct , y:: StatStruct ) # do not include `desc` in equality or hash
8081 end )
8182end
8283
83- StatStruct () = StatStruct (" " , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
84- StatStruct (buf:: Union{Vector{UInt8},Ptr{UInt8}} ) = StatStruct (" " , buf)
85- StatStruct (desc:: Union{AbstractString, OS_HANDLE} , buf:: Union{Vector{UInt8},Ptr{UInt8}} ) = StatStruct (
84+ StatStruct () = StatStruct (" " , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , Base . UV_ENOENT )
85+ StatStruct (buf:: Union{Memory{UInt8}, Vector{UInt8},Ptr{UInt8}} , ioerrno :: Int32 ) = StatStruct (" " , buf, ioerrno )
86+ StatStruct (desc:: Union{AbstractString, OS_HANDLE} , buf:: Union{Memory{UInt8}, Vector{UInt8},Ptr{UInt8}} , ioerrno :: Int32 ) = StatStruct (
8687 desc isa OS_HANDLE ? desc : String (desc),
87- ccall (:jl_stat_dev , UInt32, (Ptr{UInt8},), buf),
88- ccall (:jl_stat_ino , UInt32, (Ptr{UInt8},), buf),
89- ccall (:jl_stat_mode , UInt32, (Ptr{UInt8},), buf),
90- ccall (:jl_stat_nlink , UInt32, (Ptr{UInt8},), buf),
91- ccall (:jl_stat_uid , UInt32, (Ptr{UInt8},), buf),
92- ccall (:jl_stat_gid , UInt32, (Ptr{UInt8},), buf),
93- ccall (:jl_stat_rdev , UInt32, (Ptr{UInt8},), buf),
94- ccall (:jl_stat_size , UInt64, (Ptr{UInt8},), buf),
95- ccall (:jl_stat_blksize , UInt64, (Ptr{UInt8},), buf),
96- ccall (:jl_stat_blocks , UInt64, (Ptr{UInt8},), buf),
97- ccall (:jl_stat_mtime , Float64, (Ptr{UInt8},), buf),
98- ccall (:jl_stat_ctime , Float64, (Ptr{UInt8},), buf),
88+ ioerrno != 0 ? zero (UInt32) : ccall (:jl_stat_dev , UInt32, (Ptr{UInt8},), buf),
89+ ioerrno != 0 ? zero (UInt32) : ccall (:jl_stat_ino , UInt32, (Ptr{UInt8},), buf),
90+ ioerrno != 0 ? zero (UInt32) : ccall (:jl_stat_mode , UInt32, (Ptr{UInt8},), buf),
91+ ioerrno != 0 ? zero (UInt32) : ccall (:jl_stat_nlink , UInt32, (Ptr{UInt8},), buf),
92+ ioerrno != 0 ? zero (UInt32) : ccall (:jl_stat_uid , UInt32, (Ptr{UInt8},), buf),
93+ ioerrno != 0 ? zero (UInt32) : ccall (:jl_stat_gid , UInt32, (Ptr{UInt8},), buf),
94+ ioerrno != 0 ? zero (UInt32) : ccall (:jl_stat_rdev , UInt32, (Ptr{UInt8},), buf),
95+ ioerrno != 0 ? zero (UInt64) : ccall (:jl_stat_size , UInt64, (Ptr{UInt8},), buf),
96+ ioerrno != 0 ? zero (UInt64) : ccall (:jl_stat_blksize , UInt64, (Ptr{UInt8},), buf),
97+ ioerrno != 0 ? zero (UInt64) : ccall (:jl_stat_blocks , UInt64, (Ptr{UInt8},), buf),
98+ ioerrno != 0 ? zero (Float64) : ccall (:jl_stat_mtime , Float64, (Ptr{UInt8},), buf),
99+ ioerrno != 0 ? zero (Float64) : ccall (:jl_stat_ctime , Float64, (Ptr{UInt8},), buf),
100+ ioerrno
99101)
100102
101103function iso_datetime_with_relative (t, tnow)
@@ -130,35 +132,41 @@ end
130132function show_statstruct (io:: IO , st:: StatStruct , oneline:: Bool )
131133 print (io, oneline ? " StatStruct(" : " StatStruct for " )
132134 show (io, st. desc)
133- oneline || print (io, " \n " )
134- print (io, " size: " , st. size, " bytes" )
135- oneline || print (io, " \n " )
136- print (io, " device: " , st. device)
137- oneline || print (io, " \n " )
138- print (io, " inode: " , st. inode)
139- oneline || print (io, " \n " )
140- print (io, " mode: 0o" , string (filemode (st), base = 8 , pad = 6 ), " (" , filemode_string (st), " )" )
141- oneline || print (io, " \n " )
142- print (io, " nlink: " , st. nlink)
143- oneline || print (io, " \n " )
144- print (io, " uid: $(st. uid) " )
145- username = getusername (st. uid)
146- username === nothing || print (io, " (" , username, " )" )
147- oneline || print (io, " \n " )
148- print (io, " gid: " , st. gid)
149- groupname = getgroupname (st. gid)
150- groupname === nothing || print (io, " (" , groupname, " )" )
151- oneline || print (io, " \n " )
152- print (io, " rdev: " , st. rdev)
153- oneline || print (io, " \n " )
154- print (io, " blksz: " , st. blksize)
155- oneline || print (io, " \n " )
156- print (io, " blocks: " , st. blocks)
157- tnow = round (UInt, time ())
158- oneline || print (io, " \n " )
159- print (io, " mtime: " , iso_datetime_with_relative (st. mtime, tnow))
160- oneline || print (io, " \n " )
161- print (io, " ctime: " , iso_datetime_with_relative (st. ctime, tnow))
135+ code = st. ioerrno
136+ if code != 0
137+ print (io, oneline ? " " : " \n " )
138+ print (io, Base. uverrorname (code), " : " , Base. struverror (code))
139+ else
140+ oneline || print (io, " \n " )
141+ print (io, " size: " , st. size, " bytes" )
142+ oneline || print (io, " \n " )
143+ print (io, " device: " , st. device)
144+ oneline || print (io, " \n " )
145+ print (io, " inode: " , st. inode)
146+ oneline || print (io, " \n " )
147+ print (io, " mode: 0o" , string (filemode (st), base = 8 , pad = 6 ), " (" , filemode_string (st), " )" )
148+ oneline || print (io, " \n " )
149+ print (io, " nlink: " , st. nlink)
150+ oneline || print (io, " \n " )
151+ print (io, " uid: $(st. uid) " )
152+ username = getusername (st. uid)
153+ username === nothing || print (io, " (" , username, " )" )
154+ oneline || print (io, " \n " )
155+ print (io, " gid: " , st. gid)
156+ groupname = getgroupname (st. gid)
157+ groupname === nothing || print (io, " (" , groupname, " )" )
158+ oneline || print (io, " \n " )
159+ print (io, " rdev: " , st. rdev)
160+ oneline || print (io, " \n " )
161+ print (io, " blksz: " , st. blksize)
162+ oneline || print (io, " \n " )
163+ print (io, " blocks: " , st. blocks)
164+ tnow = round (UInt, time ())
165+ oneline || print (io, " \n " )
166+ print (io, " mtime: " , iso_datetime_with_relative (st. mtime, tnow))
167+ oneline || print (io, " \n " )
168+ print (io, " ctime: " , iso_datetime_with_relative (st. ctime, tnow))
169+ end
162170 oneline && print (io, " )" )
163171 return nothing
164172end
@@ -168,18 +176,13 @@ show(io::IO, ::MIME"text/plain", st::StatStruct) = show_statstruct(io, st, false
168176
169177# stat & lstat functions
170178
179+ checkstat (s:: StatStruct ) = Int (s. ioerrno) in (0 , Base. UV_ENOENT, Base. UV_ENOTDIR, Base. UV_EINVAL) ? s : uv_error (string (" stat(" , repr (s. desc), " )" ), s. ioerrno)
180+
171181macro stat_call (sym, arg1type, arg)
172182 return quote
173- stat_buf = zeros ( UInt8, Int (ccall (:jl_sizeof_stat , Int32, ())))
183+ stat_buf = fill! ( Memory { UInt8} (undef , Int (ccall (:jl_sizeof_stat , Int32, ()))), 0x00 )
174184 r = ccall ($ (Expr (:quote , sym)), Int32, ($ (esc (arg1type)), Ptr{UInt8}), $ (esc (arg)), stat_buf)
175- if ! (r in (0 , Base. UV_ENOENT, Base. UV_ENOTDIR, Base. UV_EINVAL))
176- uv_error (string (" stat(" , repr ($ (esc (arg))), " )" ), r)
177- end
178- st = StatStruct ($ (esc (arg)), stat_buf)
179- if ispath (st) != (r == 0 )
180- error (" stat returned zero type for a valid path" )
181- end
182- return st
185+ return checkstat (StatStruct ($ (esc (arg)), stat_buf, r))
183186 end
184187end
185188
@@ -334,7 +337,7 @@ Return `true` if a valid filesystem entity exists at `path`,
334337otherwise returns `false`.
335338This is the generalization of [`isfile`](@ref), [`isdir`](@ref) etc.
336339"""
337- ispath (st:: StatStruct ) = filemode (st) & 0xf000 != 0x0000
340+ ispath (st:: StatStruct ) = st . ioerrno == 0
338341function ispath (path:: String )
339342 # We use `access()` and `F_OK` to determine if a given path exists. `F_OK` comes from `unistd.h`.
340343 F_OK = 0x00
0 commit comments