From: Michael J. Spencer Date: Tue, 28 Dec 2010 01:49:01 +0000 (+0000) Subject: Support/PathV2: Implement has_magic. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=628467ef1f230e40ee00626ddfdcc7ca77b45a11;p=oota-llvm.git Support/PathV2: Implement has_magic. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122587 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h index 2a2daaecedf..960875e9897 100644 --- a/include/llvm/Support/FileSystem.h +++ b/include/llvm/Support/FileSystem.h @@ -448,7 +448,7 @@ error_code canonicalize(const Twine &path, SmallVectorImpl &result); /// @param magic Byte sequence to compare \a path's first len(magic) bytes to. /// @results errc::success if result has been successfully set, otherwise a /// platform specific error_code. -error_code has_magic(const Twine &path, const Twine &magic); +error_code has_magic(const Twine &path, const Twine &magic, bool &result); /// @brief Get \a path's first \a len bytes. /// diff --git a/lib/Support/PathV2.cpp b/lib/Support/PathV2.cpp index 335f7ff9194..4cfb650a6cc 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 +#include +#include 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