diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-01-14 15:37:50 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-01-14 15:37:50 +0000 |
commit | 581a6d8501ff5614297da837b81ed3b6956361ea (patch) | |
tree | 985ee91d0ca1d3e6506ac5ff7e37f5b67adfec09 /lib/Support | |
parent | 909545a822eef491158f831688066f0ec2866938 (diff) |
Diffstat (limited to 'lib/Support')
-rw-r--r-- | lib/Support/FileOutputBuffer.cpp | 66 | ||||
-rw-r--r-- | lib/Support/Host.cpp | 19 | ||||
-rw-r--r-- | lib/Support/TarWriter.cpp | 17 |
3 files changed, 74 insertions, 28 deletions
diff --git a/lib/Support/FileOutputBuffer.cpp b/lib/Support/FileOutputBuffer.cpp index 2c7bf0435d88d..57e5a8d7871cd 100644 --- a/lib/Support/FileOutputBuffer.cpp +++ b/lib/Support/FileOutputBuffer.cpp @@ -15,6 +15,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/Errc.h" +#include "llvm/Support/Path.h" #include "llvm/Support/Signals.h" #include <system_error> @@ -28,8 +29,10 @@ using llvm::sys::fs::mapped_file_region; namespace llvm { FileOutputBuffer::FileOutputBuffer(std::unique_ptr<mapped_file_region> R, - StringRef Path, StringRef TmpPath) - : Region(std::move(R)), FinalPath(Path), TempPath(TmpPath) {} + StringRef Path, StringRef TmpPath, + bool IsRegular) + : Region(std::move(R)), FinalPath(Path), TempPath(TmpPath), + IsRegular(IsRegular) {} FileOutputBuffer::~FileOutputBuffer() { // Close the mapping before deleting the temp file, so that the removal @@ -40,9 +43,10 @@ FileOutputBuffer::~FileOutputBuffer() { ErrorOr<std::unique_ptr<FileOutputBuffer>> FileOutputBuffer::create(StringRef FilePath, size_t Size, unsigned Flags) { - // If file already exists, it must be a regular file (to be mappable). + // Check file is not a regular file, in which case we cannot remove it. sys::fs::file_status Stat; std::error_code EC = sys::fs::status(FilePath, Stat); + bool IsRegular = true; switch (Stat.type()) { case sys::fs::file_type::file_not_found: // If file does not exist, we'll create one. @@ -56,25 +60,34 @@ FileOutputBuffer::create(StringRef FilePath, size_t Size, unsigned Flags) { default: if (EC) return EC; - else - return make_error_code(errc::operation_not_permitted); + IsRegular = false; } - // Delete target file. - EC = sys::fs::remove(FilePath); - if (EC) - return EC; - - unsigned Mode = sys::fs::all_read | sys::fs::all_write; - // If requested, make the output file executable. - if (Flags & F_executable) - Mode |= sys::fs::all_exe; + if (IsRegular) { + // Delete target file. + EC = sys::fs::remove(FilePath); + if (EC) + return EC; + } - // Create new file in same directory but with random name. SmallString<128> TempFilePath; int FD; - EC = sys::fs::createUniqueFile(Twine(FilePath) + ".tmp%%%%%%%", FD, - TempFilePath, Mode); + if (IsRegular) { + unsigned Mode = sys::fs::all_read | sys::fs::all_write; + // If requested, make the output file executable. + if (Flags & F_executable) + Mode |= sys::fs::all_exe; + // Create new file in same directory but with random name. + EC = sys::fs::createUniqueFile(Twine(FilePath) + ".tmp%%%%%%%", FD, + TempFilePath, Mode); + } else { + // Create a temporary file. Since this is a special file, we will not move + // it and the new file can be in another filesystem. This avoids trying to + // create a temporary file in /dev when outputting to /dev/null for example. + EC = sys::fs::createTemporaryFile(sys::path::filename(FilePath), "", FD, + TempFilePath); + } + if (EC) return EC; @@ -99,8 +112,8 @@ FileOutputBuffer::create(StringRef FilePath, size_t Size, unsigned Flags) { if (Ret) return std::error_code(errno, std::generic_category()); - std::unique_ptr<FileOutputBuffer> Buf( - new FileOutputBuffer(std::move(MappedFile), FilePath, TempFilePath)); + std::unique_ptr<FileOutputBuffer> Buf(new FileOutputBuffer( + std::move(MappedFile), FilePath, TempFilePath, IsRegular)); return std::move(Buf); } @@ -108,10 +121,19 @@ std::error_code FileOutputBuffer::commit() { // Unmap buffer, letting OS flush dirty pages to file on disk. Region.reset(); + std::error_code EC; + if (IsRegular) { + // Rename file to final name. + EC = sys::fs::rename(Twine(TempPath), Twine(FinalPath)); + sys::DontRemoveFileOnSignal(TempPath); + } else { + EC = sys::fs::copy_file(TempPath, FinalPath); + std::error_code RMEC = sys::fs::remove(TempPath); + sys::DontRemoveFileOnSignal(TempPath); + if (RMEC) + return RMEC; + } - // Rename file to final name. - std::error_code EC = sys::fs::rename(Twine(TempPath), Twine(FinalPath)); - sys::DontRemoveFileOnSignal(TempPath); return EC; } } // namespace diff --git a/lib/Support/Host.cpp b/lib/Support/Host.cpp index 8a09589aa884a..d1b40412a6fc6 100644 --- a/lib/Support/Host.cpp +++ b/lib/Support/Host.cpp @@ -111,6 +111,7 @@ enum ProcessorTypes { AMDATHLON, AMDFAM14H, AMDFAM16H, + AMDFAM17H, CPU_TYPE_MAX }; @@ -149,6 +150,7 @@ enum ProcessorSubtypes { AMD_BTVER2, AMDFAM15H_BDVER3, AMDFAM15H_BDVER4, + AMDFAM17H_ZNVER1, CPU_SUBTYPE_MAX }; @@ -742,6 +744,14 @@ static void getAMDProcessorTypeAndSubtype(unsigned int Family, } *Subtype = AMD_BTVER2; break; // "btver2" + case 23: + *Type = AMDFAM17H; + if (Features & (1 << FEATURE_ADX)) { + *Subtype = AMDFAM17H_ZNVER1; + break; // "znver1" + } + *Subtype = AMD_BTVER1; + break; default: break; // "generic" } @@ -950,6 +960,15 @@ StringRef sys::getHostCPUName() { default: return "amdfam16"; } + case AMDFAM17H: + switch (Subtype) { + case AMD_BTVER1: + return "btver1"; + case AMDFAM17H_ZNVER1: + return "znver1"; + default: + return "amdfam17"; + } default: return "generic"; } diff --git a/lib/Support/TarWriter.cpp b/lib/Support/TarWriter.cpp index f79b364dc1f7b..f06abf46cce43 100644 --- a/lib/Support/TarWriter.cpp +++ b/lib/Support/TarWriter.cpp @@ -54,6 +54,13 @@ struct UstarHeader { }; static_assert(sizeof(UstarHeader) == BlockSize, "invalid Ustar header"); +static UstarHeader makeUstarHeader() { + UstarHeader Hdr = {}; + memcpy(Hdr.Magic, "ustar", 5); // Ustar magic + memcpy(Hdr.Version, "00", 2); // Ustar version + return Hdr; +} + // A PAX attribute is in the form of "<length> <key>=<value>\n" // where <length> is the length of the entire string including // the length field itself. An example string is this. @@ -98,10 +105,9 @@ static void writePaxHeader(raw_fd_ostream &OS, StringRef Path) { std::string PaxAttr = formatPax("path", Path); // Create a 512-byte header. - UstarHeader Hdr = {}; + UstarHeader Hdr = makeUstarHeader(); snprintf(Hdr.Size, sizeof(Hdr.Size), "%011zo", PaxAttr.size()); - Hdr.TypeFlag = 'x'; // PAX magic - memcpy(Hdr.Magic, "ustar", 6); // Ustar magic + Hdr.TypeFlag = 'x'; // PAX magic computeChecksum(Hdr); // Write them down. @@ -116,7 +122,7 @@ static void writePaxHeader(raw_fd_ostream &OS, StringRef Path) { static std::pair<StringRef, StringRef> splitPath(StringRef Path) { if (Path.size() <= sizeof(UstarHeader::Name)) return {"", Path}; - size_t Sep = Path.rfind('/', sizeof(UstarHeader::Name) + 1); + size_t Sep = Path.rfind('/', sizeof(UstarHeader::Prefix) + 1); if (Sep == StringRef::npos) return {"", Path}; return {Path.substr(0, Sep), Path.substr(Sep + 1)}; @@ -138,11 +144,10 @@ static void writeUstarHeader(raw_fd_ostream &OS, StringRef Path, size_t Size) { StringRef Name; std::tie(Prefix, Name) = splitPath(Path); - UstarHeader Hdr = {}; + UstarHeader Hdr = makeUstarHeader(); memcpy(Hdr.Name, Name.data(), Name.size()); memcpy(Hdr.Mode, "0000664", 8); snprintf(Hdr.Size, sizeof(Hdr.Size), "%011zo", Size); - memcpy(Hdr.Magic, "ustar", 6); memcpy(Hdr.Prefix, Prefix.data(), Prefix.size()); computeChecksum(Hdr); OS << StringRef(reinterpret_cast<char *>(&Hdr), sizeof(Hdr)); |