/* */ #include "a2io.h" #include "util.h" #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include #else // _WIN32 #include #endif namespace aria2 { namespace util { namespace filesystem { space_info space(const char* path, std::error_code& ec) { space_info rv{static_cast(-1), static_cast(-1), static_cast(-1)}; if (!path || !*path) { path = "."; } #ifdef _WIN32 ULARGE_INTEGER sp_avail, sp_free, sp_cap; auto wpath = utf8ToWChar(path); if (GetDiskFreeSpaceExW(wpath.c_str(), &sp_avail, &sp_cap, &sp_free)) { rv.capacity = static_cast(sp_cap.QuadPart); rv.available = static_cast(sp_avail.QuadPart); rv.free = static_cast(sp_free.QuadPart); ec.clear(); } else { ec.assign(GetLastError(), std::system_category()); } #else // _WIN32 struct statvfs st; if (!statvfs(path, &st)) { rv.capacity = static_cast(st.f_blocks) * st.f_frsize; rv.free = static_cast(st.f_bfree) * st.f_frsize; rv.available = static_cast(st.f_bavail) * st.f_frsize; ec.clear(); } else { ec.assign(errno, std::system_category()); } #endif // _WIN32 return rv; } space_info space_downwards(const char* path, std::error_code& ec) { auto rv = space(path, ec); if (!ec) { return rv; } std::string spath(path); for (;;) { if (spath.empty()) { break; } #if _WIN32 if (spath == "\\\\") { // raw UNC prefix break; } #endif auto pos = spath.find_last_of("/\\"); if (pos == std::string::npos) { spath = ""; } else { spath = spath.substr(0, pos); } rv = space(spath.c_str(), ec); if (!ec) { break; } } return rv; } } // namespace filesystem } // namespace util } // namespace aria2