diff --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.space/space.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.space/space.pass.cpp --- a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.space/space.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.space/space.pass.cpp @@ -14,7 +14,6 @@ // space_info space(const path& p, error_code& ec) noexcept; #include "filesystem_include.h" -#include #include "test_macros.h" #include "rapid-cxx-test.h" @@ -85,23 +84,12 @@ // All the test cases should reside on the same filesystem and therefore // should have the same expected result. Compute this expected result // one and check that it looks semi-sane. - struct statvfs expect; - TEST_REQUIRE(::statvfs(static_env.Dir.string().c_str(), &expect) != -1); - TEST_CHECK(expect.f_bavail > 0); - TEST_CHECK(expect.f_bfree > 0); - TEST_CHECK(expect.f_bsize > 0); - TEST_CHECK(expect.f_blocks > 0); - TEST_REQUIRE(expect.f_frsize > 0); - auto do_mult = [&](std::uintmax_t val) { - std::uintmax_t fsize = expect.f_frsize; - std::uintmax_t new_val = val * fsize; - TEST_CHECK(new_val / fsize == val); // Test for overflow - return new_val; - }; const std::uintmax_t bad_value = static_cast(-1); - const std::uintmax_t expect_capacity = do_mult(expect.f_blocks); - const std::uintmax_t expect_free = do_mult(expect.f_bfree); - const std::uintmax_t expect_avail = do_mult(expect.f_bavail); + std::uintmax_t expect_capacity; + std::uintmax_t expect_free; + std::uintmax_t expect_avail; + TEST_REQUIRE(utils::space(static_env.Dir.string(), expect_capacity, + expect_free, expect_avail)); // Other processes running on the operating system may have changed // the amount of space available. Check that these are within tolerances. diff --git a/libcxx/test/support/filesystem_test_helper.h b/libcxx/test/support/filesystem_test_helper.h --- a/libcxx/test/support/filesystem_test_helper.h +++ b/libcxx/test/support/filesystem_test_helper.h @@ -6,6 +6,7 @@ #include // for stat, mkdir, mkfifo #ifndef _WIN32 #include // for ftruncate, link, symlink, getcwd, chdir +#include #else #include #include @@ -52,6 +53,21 @@ inline int unsetenv(const char *var) { return ::_putenv((std::string(var) + "=").c_str()); } + inline bool space(std::string path, std::uintmax_t &capacity, + std::uintmax_t &free, std::uintmax_t &avail) { + ULARGE_INTEGER FreeBytesAvailableToCaller, TotalNumberOfBytes, + TotalNumberOfFreeBytes; + if (!GetDiskFreeSpaceExA(path.c_str(), &FreeBytesAvailableToCaller, + &TotalNumberOfBytes, &TotalNumberOfFreeBytes)) + return false; + capacity = TotalNumberOfBytes.QuadPart; + free = TotalNumberOfFreeBytes.QuadPart; + avail = FreeBytesAvailableToCaller.QuadPart; + assert(capacity > 0); + assert(free > 0); + assert(avail > 0); + return true; + } #else using ::mkdir; using ::ftruncate; @@ -63,6 +79,27 @@ inline int unsetenv(const char *var) { return ::unsetenv(var); } + inline bool space(std::string path, std::uintmax_t &capacity, + std::uintmax_t &free, std::uintmax_t &avail) { + struct statvfs expect; + if (::statvfs(path.c_str(), &expect) == -1) + return false; + assert(expect.f_bavail > 0); + assert(expect.f_bfree > 0); + assert(expect.f_bsize > 0); + assert(expect.f_blocks > 0); + assert(expect.f_frsize > 0); + auto do_mult = [&](std::uintmax_t val) { + std::uintmax_t fsize = expect.f_frsize; + std::uintmax_t new_val = val * fsize; + assert(new_val / fsize == val); // Test for overflow + return new_val; + }; + capacity = do_mult(expect.f_blocks); + free = do_mult(expect.f_bfree); + avail = do_mult(expect.f_bavail); + return true; + } #endif inline std::string getcwd() {