Skip to content

Commit

Permalink
Add diskstat() function returning statistics of the disk. (JuliaLang#…
Browse files Browse the repository at this point in the history
  • Loading branch information
li1 committed Oct 30, 2021
1 parent a387724 commit 4a12d1e
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 0 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ New library functions
---------------------

* `hardlink(src, dst)` can be used to create hard links. ([#41639])
* `diskstat(path=pwd())` can be used to return statistics about the disk. ([#42248])

New library features
--------------------
Expand Down
1 change: 1 addition & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -893,6 +893,7 @@ export
chown,
cp,
ctime,
diskstat,
download,
filemode,
filesize,
Expand Down
59 changes: 59 additions & 0 deletions base/file.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export
chown,
cp,
cptree,
diskstat,
hardlink,
mkdir,
mkpath,
Expand Down Expand Up @@ -1168,3 +1169,61 @@ function chown(path::AbstractString, owner::Integer, group::Integer=-1)
err < 0 && uv_error("chown($(repr(path)), $owner, $group)", err)
path
end


# - https://docs.libuv.org/en/v1.x/fs.html#c.uv_fs_statfs (libuv function docs)
# - https://docs.libuv.org/en/v1.x/fs.html#c.uv_statfs_t (libuv docs of the returned struct)
"""
DiskStat
Stores information about the disk in bytes. Populate by calling `diskstat`.
"""
struct DiskStat
ftype::UInt64
bsize::UInt64
blocks::UInt64
bfree::UInt64
bavail::UInt64
files::UInt64
ffree::UInt64
fspare::NTuple{4, UInt64} # reserved
end

function Base.getproperty(stats::DiskStat, field::Symbol)
total = getfield(stats, :bsize) * getfield(stats, :blocks)
available = getfield(stats, :bsize) * getfield(stats, :bavail)
field === :available && return available
field === :total && return total
field === :used && return total - available
return getfield(stats, field)
end

@eval Base.propertynames(stats::DiskStat) = $((fieldnames(DiskStat)[1:end-1]..., :available, :total, :used))

function Base.show(io::IO, x::DiskStat)
print(io, "DiskStat(")
for field in 1:(nfields(x) - 1)
print(io, "$(getfield(x, field)), ")
end
print(io, "available: $(x.available), total: $(x.total), used: $(x.used))")
end

"""
diskstat(path=pwd())
Returns statistics in bytes about the disk that contains the file or directory pointed at by
`path`. If no argument is passed, statistics about the disk that contains the current
working directory are returned.
!!! compat "Julia 1.8"
This method was added in Julia 1.8.
"""
function diskstat(path::AbstractString=pwd())
req = zeros(UInt8, _sizeof_uv_fs)
err = ccall(:uv_fs_statfs, Cint, (Ptr{Cvoid}, Ptr{Cvoid}, Cstring, Ptr{Cvoid}),
C_NULL, req, path, C_NULL)
err < 0 && uv_error("diskstat($(repr(path)))", err)
statfs_ptr = ccall(:jl_uv_fs_t_ptr, Ptr{Nothing}, (Ptr{Cvoid},), req)

return unsafe_load(reinterpret(Ptr{DiskStat}, statfs_ptr))
end
1 change: 1 addition & 0 deletions doc/src/base/file.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Base.Filesystem.chmod
Base.Filesystem.chown
Base.RawFD
Base.stat
Base.Filesystem.diskstat
Base.Filesystem.lstat
Base.Filesystem.ctime
Base.Filesystem.mtime
Expand Down
14 changes: 14 additions & 0 deletions test/file.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1695,3 +1695,17 @@ end
@test !isnothing(Base.Filesystem.getgroupname(s.gid))
end
end

@testset "diskstat() works" begin
# Sanity check assuming disk is smaller than 32PB
PB = Int64(2)^44

dstat = diskstat()
@test dstat.total < 32PB
@test dstat.used + dstat.available == dstat.total
@test occursin(r"^DiskStat\(.*, available: \d+, total: \d+, used: \d+\)$", sprint(show, dstat))
# Test diskstat(::AbstractString)
dstat = diskstat(pwd())
@test dstat.total < 32PB
@test dstat.used + dstat.available == dstat.total
end

0 comments on commit 4a12d1e

Please sign in to comment.