Index: include/llvm/Support/FileSystem.h =================================================================== --- include/llvm/Support/FileSystem.h +++ include/llvm/Support/FileSystem.h @@ -32,6 +32,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ErrorOr.h" #include "llvm/Support/TimeValue.h" #include #include @@ -648,6 +649,15 @@ std::error_code getUniqueID(const Twine Path, UniqueID &Result); +/// @brief Get disk space usage information. +/// +/// @param Path Input path. +/// @param SpaceInfo Set to the capacity, free, and available space on the +/// device \a Path is on. +/// @results errc::success if result has been successfully set, otherwise a +/// platform specific error_code. +ErrorOr disk_space(const Twine Path); + /// This class represents a memory mapped file. It is based on /// boost::iostreams::mapped_file. class mapped_file_region { Index: lib/Support/Unix/Path.inc =================================================================== --- lib/Support/Unix/Path.inc +++ lib/Support/Unix/Path.inc @@ -60,6 +60,24 @@ # define PATH_MAX 4096 #endif +#include +#if !defined(__APPLE__) && !defined(__OpenBSD__) && !defined(__ANDROID__) +# include +# define STATVFS statvfs +# define STATVFS_F_FRSIZE(vfs) vfs.f_frsize +#else +# ifdef __OpenBSD__ +# include +# elif defined(__ANDROID__) +# include +# else +# include +# endif +# define STATVFS statfs +# define STATVFS_F_FRSIZE(vfs) static_cast(vfs.f_bsize) +#endif + + using namespace llvm; namespace llvm { @@ -190,6 +208,19 @@ return UniqueID(fs_st_dev, fs_st_ino); } +ErrorOr disk_space(const Twine Path) { + struct STATVFS Vfs; + if(::STATVFS(Path.str().c_str(), &Vfs)) + return std::error_code(errno, std::generic_category()); + space_info SpaceInfo; + SpaceInfo.capacity = + static_cast(Vfs.f_blocks)* STATVFS_F_FRSIZE(Vfs); + SpaceInfo.free = static_cast(Vfs.f_bfree)* STATVFS_F_FRSIZE(Vfs); + SpaceInfo.available = + static_cast(Vfs.f_bavail)* STATVFS_F_FRSIZE(Vfs); + return SpaceInfo; +} + std::error_code current_path(SmallVectorImpl &result) { result.clear(); Index: lib/Support/Windows/Path.inc =================================================================== --- lib/Support/Windows/Path.inc +++ lib/Support/Windows/Path.inc @@ -151,6 +151,20 @@ return UniqueID(VolumeSerialNumber, FileID); } +ErrorOr disk_space(const Twine Path) { + PULARGE_INTEGER avail, total, free; + if (!::GetDiskFreeSpaceExW(Path.str().c_str(), &avail, &total, &free)) + return mapWindowsError(::GetLastError()); + space_info SpaceInfo; + SpaceInfo.capacity = (static_cast(total.HighPart) << 32) + + total.LowPart; + SpaceInfo.free = (static_cast(free.HighPart) << 32) + + free.LowPart; + SpaceInfo.available = (static_cast(avail.HighPart) << 32) + + avail.LowPart; + return SpaceInfo; +} + TimeValue file_status::getLastAccessedTime() const { ULARGE_INTEGER UI; UI.LowPart = LastAccessedTimeLow;