From f555637cc9cf5e9931b4331cf4ce0f2cbbec0755 Mon Sep 17 00:00:00 2001 From: kbkpbot Date: Sun, 2 Feb 2025 20:55:38 +0800 Subject: [PATCH 1/6] os:add disk_usage() --- vlib/builtin/cfns.c.v | 2 ++ vlib/os/os_nix.c.v | 31 +++++++++++++++++++++++++++++++ vlib/os/os_test.c.v | 7 +++++++ vlib/os/os_windows.c.v | 22 ++++++++++++++++++++++ 4 files changed, 62 insertions(+) diff --git a/vlib/builtin/cfns.c.v b/vlib/builtin/cfns.c.v index bffec65d28e793..b4fde0c56ad696 100644 --- a/vlib/builtin/cfns.c.v +++ b/vlib/builtin/cfns.c.v @@ -513,3 +513,5 @@ fn C.WrappedNSLog(str &u8) // absolute value @[trusted] fn C.abs(number int) int + +fn C.GetDiskFreeSpaceExA(path charptr, free_bytes_available_to_caller &u64, total_number_of_bytes &u64, total_number_of_free_bytes &u64) bool diff --git a/vlib/os/os_nix.c.v b/vlib/os/os_nix.c.v index 681b88e98cbdbf..0a07bbe1010ce5 100644 --- a/vlib/os/os_nix.c.v +++ b/vlib/os/os_nix.c.v @@ -7,6 +7,7 @@ import strings #include #include #include +#include #include // path_separator is the platform specific separator string, used between the folders @@ -530,3 +531,33 @@ 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 +} + +fn C.statvfs(path charptr, vfs &C.statvfs) int + +// disk_usage returns disk usage of `path` +// Examples: +// ```v +// total,available,used := os.disk_usage('.') +// ``` +@[manualfree] +pub fn disk_usage(path string) !(u64, u64, u64) { + mpath := if path == '' { '.' } else { path } + defer { unsafe { mpath.free() } } + mut vfs := C.statvfs{} + ret := C.statvfs(mpath.str, &vfs) + if ret == -1 { + return error('can\`t 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 f_bsize * f_blocks, f_bsize * f_bavail, f_bsize * (f_blocks - f_bfree) +} diff --git a/vlib/os/os_test.c.v b/vlib/os/os_test.c.v index 7d8e155306fe73..45c2a59011e796 100644 --- a/vlib/os/os_test.c.v +++ b/vlib/os/os_test.c.v @@ -1110,3 +1110,10 @@ fn test_mkdir_at_file_dst() { } assert false } + +fn test_disk_usage() { + total, available, used := os.disk_usage('.')! + assert total > 0 + assert available > 0 + assert used > 0 +} diff --git a/vlib/os/os_windows.c.v b/vlib/os/os_windows.c.v index e36a30d4e52486..2fc3e5eafe3fda 100644 --- a/vlib/os/os_windows.c.v +++ b/vlib/os/os_windows.c.v @@ -601,3 +601,25 @@ pub fn page_size() int { C.GetSystemInfo(&sinfo) return int(sinfo.dwPageSize) } + +// disk_usage returns disk usage of `path` +// Examples: +// ```v +// total,available,used := os.disk_usage('.') +// ``` +pub fn disk_usage(path string) !(u64, u64, u64) { + 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(0, &free_bytes_available_to_caller, &total, &available) + } else { + ret = C.GetDiskFreeSpaceExA(path.str, &free_bytes_available_to_caller, &total, + &available) + } + if ret == false { + return error("can't get disk usage of path") + } + return total, available, total - available +} From 60320e67838a9d73d99bd1f63c921bf4d369a16d Mon Sep 17 00:00:00 2001 From: kbkpbot Date: Sun, 2 Feb 2025 21:01:22 +0800 Subject: [PATCH 2/6] fix msg --- vlib/os/os_nix.c.v | 2 +- vlib/os/os_windows.c.v | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/vlib/os/os_nix.c.v b/vlib/os/os_nix.c.v index 0a07bbe1010ce5..66e6d345df2bff 100644 --- a/vlib/os/os_nix.c.v +++ b/vlib/os/os_nix.c.v @@ -553,7 +553,7 @@ pub fn disk_usage(path string) !(u64, u64, u64) { mut vfs := C.statvfs{} ret := C.statvfs(mpath.str, &vfs) if ret == -1 { - return error('can\`t get disk_usage of path') + return error('can\`t get disk usage of path') } f_bsize := u64(vfs.f_bsize) f_blocks := u64(vfs.f_blocks) diff --git a/vlib/os/os_windows.c.v b/vlib/os/os_windows.c.v index 2fc3e5eafe3fda..3c64bc20b75e37 100644 --- a/vlib/os/os_windows.c.v +++ b/vlib/os/os_windows.c.v @@ -619,7 +619,7 @@ pub fn disk_usage(path string) !(u64, u64, u64) { &available) } if ret == false { - return error("can't get disk usage of path") + return error('can\`t get disk usage of path') } return total, available, total - available } From 6cd8253f34aa0d43e69fdf2d180c36e8c1806ab8 Mon Sep 17 00:00:00 2001 From: kbkpbot Date: Sun, 2 Feb 2025 23:04:36 +0800 Subject: [PATCH 3/6] use DiskUsage struct --- vlib/os/os.c.v | 7 +++++++ vlib/os/os_nix.c.v | 12 ++++++------ vlib/os/os_test.c.v | 8 ++++---- vlib/os/os_windows.c.v | 12 ++++++------ 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/vlib/os/os.c.v b/vlib/os/os.c.v index a5ebd2ee062373..ec74beb3bcea02 100644 --- a/vlib/os/os.c.v +++ b/vlib/os/os.c.v @@ -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 +} diff --git a/vlib/os/os_nix.c.v b/vlib/os/os_nix.c.v index 66e6d345df2bff..8953d3f8b8c9d4 100644 --- a/vlib/os/os_nix.c.v +++ b/vlib/os/os_nix.c.v @@ -542,12 +542,8 @@ struct C.statvfs { fn C.statvfs(path charptr, vfs &C.statvfs) int // disk_usage returns disk usage of `path` -// Examples: -// ```v -// total,available,used := os.disk_usage('.') -// ``` @[manualfree] -pub fn disk_usage(path string) !(u64, u64, u64) { +pub fn disk_usage(path string) !DiskUsage { mpath := if path == '' { '.' } else { path } defer { unsafe { mpath.free() } } mut vfs := C.statvfs{} @@ -559,5 +555,9 @@ pub fn disk_usage(path string) !(u64, u64, u64) { f_blocks := u64(vfs.f_blocks) f_bavail := u64(vfs.f_bavail) f_bfree := u64(vfs.f_bfree) - return f_bsize * f_blocks, f_bsize * f_bavail, f_bsize * (f_blocks - f_bfree) + return DiskUsage{ + total: f_bsize * f_blocks + available: f_bsize * f_bavail + used: f_bsize * (f_blocks - f_bfree) + } } diff --git a/vlib/os/os_test.c.v b/vlib/os/os_test.c.v index 45c2a59011e796..3ea7ee401dae4c 100644 --- a/vlib/os/os_test.c.v +++ b/vlib/os/os_test.c.v @@ -1112,8 +1112,8 @@ fn test_mkdir_at_file_dst() { } fn test_disk_usage() { - total, available, used := os.disk_usage('.')! - assert total > 0 - assert available > 0 - assert used > 0 + usage := os.disk_usage('.')! + assert usage.total > 0 + assert usage.available > 0 + assert usage.used > 0 } diff --git a/vlib/os/os_windows.c.v b/vlib/os/os_windows.c.v index 3c64bc20b75e37..1d8bf5664b6214 100644 --- a/vlib/os/os_windows.c.v +++ b/vlib/os/os_windows.c.v @@ -603,11 +603,7 @@ pub fn page_size() int { } // disk_usage returns disk usage of `path` -// Examples: -// ```v -// total,available,used := os.disk_usage('.') -// ``` -pub fn disk_usage(path string) !(u64, u64, u64) { +pub fn disk_usage(path string) !DiskUsage { mut free_bytes_available_to_caller := u64(0) mut total := u64(0) mut available := u64(0) @@ -621,5 +617,9 @@ pub fn disk_usage(path string) !(u64, u64, u64) { if ret == false { return error('can\`t get disk usage of path') } - return total, available, total - available + return DiskUsage{ + total: total + available: available + used: total - available + } } From 90da7da775962f96e7f4bdf8fef3cb3c42b7221e Mon Sep 17 00:00:00 2001 From: kbkpbot Date: Sun, 2 Feb 2025 23:26:23 +0800 Subject: [PATCH 4/6] fix -cstrict --- vlib/builtin/cfns.c.v | 4 +++- vlib/os/os_nix.c.v | 4 +--- vlib/os/os_windows.c.v | 7 ++++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/vlib/builtin/cfns.c.v b/vlib/builtin/cfns.c.v index b4fde0c56ad696..f8332c25cc0bfe 100644 --- a/vlib/builtin/cfns.c.v +++ b/vlib/builtin/cfns.c.v @@ -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 @@ -514,4 +516,4 @@ fn C.WrappedNSLog(str &u8) @[trusted] fn C.abs(number int) int -fn C.GetDiskFreeSpaceExA(path charptr, free_bytes_available_to_caller &u64, total_number_of_bytes &u64, total_number_of_free_bytes &u64) bool +fn C.GetDiskFreeSpaceExA(const_path &char, free_bytes_available_to_caller &u64, total_number_of_bytes &u64, total_number_of_free_bytes &u64) bool diff --git a/vlib/os/os_nix.c.v b/vlib/os/os_nix.c.v index 8953d3f8b8c9d4..8847114596abbd 100644 --- a/vlib/os/os_nix.c.v +++ b/vlib/os/os_nix.c.v @@ -539,15 +539,13 @@ struct C.statvfs { f_bavail usize } -fn C.statvfs(path charptr, vfs &C.statvfs) int - // 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 := C.statvfs(mpath.str, &vfs) + ret := unsafe { C.statvfs(&char(mpath.str), &vfs) } if ret == -1 { return error('can\`t get disk usage of path') } diff --git a/vlib/os/os_windows.c.v b/vlib/os/os_windows.c.v index 1d8bf5664b6214..7c55b10db0423f 100644 --- a/vlib/os/os_windows.c.v +++ b/vlib/os/os_windows.c.v @@ -609,10 +609,11 @@ pub fn disk_usage(path string) !DiskUsage { mut available := u64(0) mut ret := false if path == '.' || path == '' { - ret = C.GetDiskFreeSpaceExA(0, &free_bytes_available_to_caller, &total, &available) - } else { - ret = C.GetDiskFreeSpaceExA(path.str, &free_bytes_available_to_caller, &total, + 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('can\`t get disk usage of path') From e75e3d179518a1683e36b77b1916005788651a4a Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sun, 2 Feb 2025 19:31:23 +0200 Subject: [PATCH 5/6] Update vlib/os/os_nix.c.v Co-authored-by: JalonSolov --- vlib/os/os_nix.c.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vlib/os/os_nix.c.v b/vlib/os/os_nix.c.v index 8847114596abbd..194e0233a0211c 100644 --- a/vlib/os/os_nix.c.v +++ b/vlib/os/os_nix.c.v @@ -547,7 +547,7 @@ pub fn disk_usage(path string) !DiskUsage { mut vfs := C.statvfs{} ret := unsafe { C.statvfs(&char(mpath.str), &vfs) } if ret == -1 { - return error('can\`t get disk usage of path') + return error('cannot get disk usage of path') } f_bsize := u64(vfs.f_bsize) f_blocks := u64(vfs.f_blocks) From 2613c3bbcb755144accc19b41335b0d23ef5ed54 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sun, 2 Feb 2025 19:31:31 +0200 Subject: [PATCH 6/6] Update vlib/os/os_windows.c.v Co-authored-by: JalonSolov --- vlib/os/os_windows.c.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vlib/os/os_windows.c.v b/vlib/os/os_windows.c.v index 7c55b10db0423f..06f35107e13ad4 100644 --- a/vlib/os/os_windows.c.v +++ b/vlib/os/os_windows.c.v @@ -616,7 +616,7 @@ pub fn disk_usage(path string) !DiskUsage { &total, &available) } if ret == false { - return error('can\`t get disk usage of path') + return error('cannot get disk usage of path') } return DiskUsage{ total: total