From: Mehdi Amini Date: Thu, 31 Mar 2016 20:48:27 +0000 (+0000) Subject: Add disk_space() to llvm::fs X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9defda528e54bd6d34f2f26b6a7822523072f3cf;p=platform%2Fupstream%2Fllvm.git Add disk_space() to llvm::fs Summary: Adapted from Boost::filesystem. Reviewers: bruno, silvas Subscribers: tberghammer, danalbert, llvm-commits, srhines Differential Revision: http://reviews.llvm.org/D18467 From: Mehdi Amini llvm-svn: 265050 --- diff --git a/llvm/include/llvm/Support/FileSystem.h b/llvm/include/llvm/Support/FileSystem.h index 4a4c3f4..0c2ac3f 100644 --- a/llvm/include/llvm/Support/FileSystem.h +++ b/llvm/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,18 @@ std::error_code identify_magic(const Twine &path, file_magic &result); std::error_code getUniqueID(const Twine Path, UniqueID &Result); +/// @brief Get disk space usage information. +/// +/// Note: Users must be careful about "Time Of Check, Time Of Use" kind of bug. +/// Note: Windows reports results according to the quota allocated to the user. +/// +/// @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 { diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc index a80e0dd..f79c463 100644 --- a/llvm/lib/Support/Unix/Path.inc +++ b/llvm/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 { @@ -70,7 +88,7 @@ namespace fs { defined(__linux__) || defined(__CYGWIN__) || defined(__DragonFly__) static int test_dir(char ret[PATH_MAX], const char *dir, const char *bin) -{ +{ struct stat sb; char fullpath[PATH_MAX]; @@ -190,6 +208,18 @@ UniqueID file_status::getUniqueID() const { 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()); + auto FrSize = STATVFS_F_FRSIZE(Vfs); + space_info SpaceInfo; + SpaceInfo.capacity = static_cast(Vfs.f_blocks) * FrSize; + SpaceInfo.free = static_cast(Vfs.f_bfree) * FrSize; + SpaceInfo.available = static_cast(Vfs.f_bavail) * FrSize; + return SpaceInfo; +} + std::error_code current_path(SmallVectorImpl &result) { result.clear(); diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc index 98fd7b0..f55260a 100644 --- a/llvm/lib/Support/Windows/Path.inc +++ b/llvm/lib/Support/Windows/Path.inc @@ -151,6 +151,19 @@ UniqueID file_status::getUniqueID() const { 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;