Skip to content

Commit

Permalink
os: add disk_usage/1 (#23634)
Browse files Browse the repository at this point in the history
  • Loading branch information
kbkpbot authored Feb 2, 2025
1 parent d4298ca commit d78bf11
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 0 deletions.
4 changes: 4 additions & 0 deletions vlib/builtin/cfns.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ fn C.stat(&char, voidptr) int

fn C.lstat(path &char, buf &C.stat) int

fn C.statvfs(const_path &char, buf &C.statvfs) int

fn C.rename(old_filename &char, new_filename &char) int

fn C.fgets(str &char, n int, stream &C.FILE) int
Expand Down Expand Up @@ -513,3 +515,5 @@ fn C.WrappedNSLog(str &u8)
// absolute value
@[trusted]
fn C.abs(number int) int

fn C.GetDiskFreeSpaceExA(const_path &char, free_bytes_available_to_caller &u64, total_number_of_bytes &u64, total_number_of_free_bytes &u64) bool
7 changes: 7 additions & 0 deletions vlib/os/os.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -1073,3 +1073,10 @@ pub fn error_win32(e SystemError) IError {
panic('Win32 API not available on this platform.')
}
}

pub struct DiskUsage {
pub:
total u64
available u64
used u64
}
29 changes: 29 additions & 0 deletions vlib/os/os_nix.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import strings
#include <fcntl.h>
#include <sys/utsname.h>
#include <sys/types.h>
#include <sys/statvfs.h>
#include <utime.h>

// path_separator is the platform specific separator string, used between the folders
Expand Down Expand Up @@ -530,3 +531,31 @@ fn C.sysconf(name int) i64
pub fn page_size() int {
return int(C.sysconf(C._SC_PAGESIZE))
}

struct C.statvfs {
f_bsize usize
f_blocks usize
f_bfree usize
f_bavail usize
}

// disk_usage returns disk usage of `path`
@[manualfree]
pub fn disk_usage(path string) !DiskUsage {
mpath := if path == '' { '.' } else { path }
defer { unsafe { mpath.free() } }
mut vfs := C.statvfs{}
ret := unsafe { C.statvfs(&char(mpath.str), &vfs) }
if ret == -1 {
return error('cannot get disk usage of path')
}
f_bsize := u64(vfs.f_bsize)
f_blocks := u64(vfs.f_blocks)
f_bavail := u64(vfs.f_bavail)
f_bfree := u64(vfs.f_bfree)
return DiskUsage{
total: f_bsize * f_blocks
available: f_bsize * f_bavail
used: f_bsize * (f_blocks - f_bfree)
}
}
7 changes: 7 additions & 0 deletions vlib/os/os_test.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -1110,3 +1110,10 @@ fn test_mkdir_at_file_dst() {
}
assert false
}

fn test_disk_usage() {
usage := os.disk_usage('.')!
assert usage.total > 0
assert usage.available > 0
assert usage.used > 0
}
23 changes: 23 additions & 0 deletions vlib/os/os_windows.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -601,3 +601,26 @@ pub fn page_size() int {
C.GetSystemInfo(&sinfo)
return int(sinfo.dwPageSize)
}

// disk_usage returns disk usage of `path`
pub fn disk_usage(path string) !DiskUsage {
mut free_bytes_available_to_caller := u64(0)
mut total := u64(0)
mut available := u64(0)
mut ret := false
if path == '.' || path == '' {
ret = C.GetDiskFreeSpaceExA(&char(0), &free_bytes_available_to_caller, &total,
&available)
} else {
ret = C.GetDiskFreeSpaceExA(&char(path.str), &free_bytes_available_to_caller,
&total, &available)
}
if ret == false {
return error('cannot get disk usage of path')
}
return DiskUsage{
total: total
available: available
used: total - available
}
}

0 comments on commit d78bf11

Please sign in to comment.