diff --git a/Libraries/LibFileSystem/FileSystem.cpp b/Libraries/LibFileSystem/FileSystem.cpp index d860e6007d..b3ca9dcddf 100644 --- a/Libraries/LibFileSystem/FileSystem.cpp +++ b/Libraries/LibFileSystem/FileSystem.cpp @@ -11,12 +11,16 @@ #include #include -#if !defined(AK_OS_IOS) && defined(AK_OS_BSD_GENERIC) -# include -#elif defined(AK_OS_LINUX) -# include -#elif defined(AK_OS_WINDOWS) +#if defined(AK_OS_WINDOWS) # include +#else +# include + +# if !defined(AK_OS_IOS) && defined(AK_OS_BSD_GENERIC) +# include +# elif defined(AK_OS_LINUX) +# include +# endif #endif // On Linux distros that use glibc `basename` is defined as a macro that expands to `__xpg_basename`, so we undefine it @@ -363,4 +367,30 @@ ErrorOr size_from_fstat(int fd) return st.st_size; } +ErrorOr compute_disk_space(LexicalPath const& path) +{ +#if defined(AK_OS_WINDOWS) + ULARGE_INTEGER free_bytes; + ULARGE_INTEGER total_bytes; + + if (!GetDiskFreeSpaceExA(path.string().characters(), &free_bytes, &total_bytes, nullptr)) + return Error::from_windows_error(); + + return DiskSpace { + .free_bytes = free_bytes.QuadPart, + .total_bytes = total_bytes.QuadPart, + }; +#else + struct statvfs stats {}; + + if (::statvfs(path.string().characters(), &stats) != 0) + return Error::from_syscall("statvfs"sv, errno); + + return DiskSpace { + .free_bytes = stats.f_bavail * stats.f_frsize, + .total_bytes = stats.f_blocks * stats.f_frsize, + }; +#endif +} + } diff --git a/Libraries/LibFileSystem/FileSystem.h b/Libraries/LibFileSystem/FileSystem.h index 0ad84cd4c6..3e0074b74c 100644 --- a/Libraries/LibFileSystem/FileSystem.h +++ b/Libraries/LibFileSystem/FileSystem.h @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -65,4 +66,10 @@ ErrorOr size_from_stat(StringView path); ErrorOr size_from_fstat(int fd); bool can_delete_or_move(StringView path); +struct DiskSpace { + u64 free_bytes { 0 }; + u64 total_bytes { 0 }; +}; +ErrorOr compute_disk_space(LexicalPath const&); + }