diff options
Diffstat (limited to 'lib/Support/PathV2.cpp')
-rw-r--r-- | lib/Support/PathV2.cpp | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/lib/Support/PathV2.cpp b/lib/Support/PathV2.cpp index 335f7ff919..4cfb650a6c 100644 --- a/lib/Support/PathV2.cpp +++ b/lib/Support/PathV2.cpp @@ -15,6 +15,8 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/ErrorHandling.h" #include <cctype> +#include <cstdio> +#include <cstring> namespace { using llvm::StringRef; @@ -659,6 +661,42 @@ void directory_entry::replace_filename(const Twine &filename, file_status st, SymlinkStatus = symlink_st; } +error_code has_magic(const Twine &path, const Twine &magic, bool &result) { + SmallString<128> PathStorage; + SmallString<32> MagicStorage; + StringRef Path = path.toNullTerminatedStringRef(PathStorage); + StringRef Magic = magic.toNullTerminatedStringRef(MagicStorage); + + assert(Magic.size() > 0 && "magic must be non-empty!"); + + SmallString<32> BufferStorage; + BufferStorage.reserve(Magic.size()); + + // Open file. + std::FILE *file = std::fopen(Path.data(), "rb"); + if (file == 0) + return error_code(errno, posix_category()); + int size = ::fread(BufferStorage.data(), 1, Magic.size(), file); + if (size != Magic.size()) { + int error = errno; + bool eof = std::feof(file) != 0; + std::fclose(file); + if (eof) { + // EOF, return false. + result = false; + return success; + } + return error_code(error, posix_category()); + } + std::fclose(file); + + if (std::memcmp(BufferStorage.data(), Magic.data(), Magic.size()) != 0) + result = false; + else + result = true; + return success; +} + } // end namespace fs } // end namespace sys } // end namespace llvm |