X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FSupport%2FFileOutputBuffer.cpp;h=94bcdc58a8062d2c2a9179a3a6811044b40fa3bf;hb=6238162cc518a915aba296ddda24311d4974290f;hp=7dc9587caae29529bcc0bf6d7f7fd4dfd5e37354;hpb=adfe2637b839efe041165f27c9ad57e3befb2be0;p=oota-llvm.git diff --git a/lib/Support/FileOutputBuffer.cpp b/lib/Support/FileOutputBuffer.cpp index 7dc9587caae..94bcdc58a80 100644 --- a/lib/Support/FileOutputBuffer.cpp +++ b/lib/Support/FileOutputBuffer.cpp @@ -11,43 +11,33 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Support/Errc.h" #include "llvm/Support/FileOutputBuffer.h" - -#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/Support/FileSystem.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Support/system_error.h" +#include +using llvm::sys::fs::mapped_file_region; namespace llvm { - - -FileOutputBuffer::FileOutputBuffer(uint8_t *Start, uint8_t *End, - StringRef Path, StringRef TmpPath) - : BufferStart(Start), BufferEnd(End) { - FinalPath.assign(Path); - TempPath.assign(TmpPath); +FileOutputBuffer::FileOutputBuffer(mapped_file_region * R, + StringRef Path, StringRef TmpPath) + : Region(R) + , FinalPath(Path) + , TempPath(TmpPath) { } - FileOutputBuffer::~FileOutputBuffer() { - // If not already commited, delete buffer and remove temp file. - if ( BufferStart != NULL ) { - sys::fs::unmap_file_pages((void*)BufferStart, getBufferSize()); - bool Existed; - sys::fs::remove(Twine(TempPath), Existed); - } + sys::fs::remove(Twine(TempPath)); } - -error_code FileOutputBuffer::create(StringRef FilePath, - size_t Size, - OwningPtr &Result, - unsigned Flags) { +std::error_code +FileOutputBuffer::create(StringRef FilePath, size_t Size, + std::unique_ptr &Result, + unsigned Flags) { // If file already exists, it must be a regular file (to be mappable). sys::fs::file_status Stat; - error_code EC = sys::fs::status(FilePath, Stat); + std::error_code EC = sys::fs::status(FilePath, Stat); switch (Stat.type()) { case sys::fs::file_type::file_not_found: // If file does not exist, we'll create one. @@ -66,83 +56,47 @@ error_code FileOutputBuffer::create(StringRef FilePath, } // Delete target file. - bool Existed; - EC = sys::fs::remove(FilePath, Existed); + 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; + // Create new file in same directory but with random name. SmallString<128> TempFilePath; int FD; - EC = sys::fs::unique_file(Twine(FilePath) + ".tmp%%%%%%%", - FD, TempFilePath, false, 0644); - if (EC) - return EC; - - // The unique_file() interface leaks lower layers and returns a file - // descriptor. There is no way to directly close it, so use this hack - // to hand it off to raw_fd_ostream to close for us. - { - raw_fd_ostream Dummy(FD, /*shouldClose=*/true); - } - - // Resize file to requested initial size - EC = sys::fs::resize_file(Twine(TempFilePath), Size); + EC = sys::fs::createUniqueFile(Twine(FilePath) + ".tmp%%%%%%%", FD, + TempFilePath, Mode); if (EC) return EC; - - // If requested, make the output file executable. - if ( Flags & F_executable ) { - sys::fs::file_status Stat2; - EC = sys::fs::status(Twine(TempFilePath), Stat2); - if (EC) - return EC; - - sys::fs::perms new_perms = Stat2.permissions(); - if ( new_perms & sys::fs::owner_read ) - new_perms |= sys::fs::owner_exe; - if ( new_perms & sys::fs::group_read ) - new_perms |= sys::fs::group_exe; - if ( new_perms & sys::fs::others_read ) - new_perms |= sys::fs::others_exe; - new_perms |= sys::fs::add_perms; - EC = sys::fs::permissions(Twine(TempFilePath), new_perms); - if (EC) - return EC; - } - // Memory map new file. - void *Base; - EC = sys::fs::map_file_pages(Twine(TempFilePath), 0, Size, true, Base); + std::unique_ptr MappedFile(new mapped_file_region( + FD, true, mapped_file_region::readwrite, Size, 0, EC)); if (EC) return EC; - - // Create FileOutputBuffer object to own mapped range. - uint8_t *Start = reinterpret_cast(Base); - Result.reset(new FileOutputBuffer(Start, Start+Size, FilePath, TempFilePath)); - - return error_code::success(); -} + Result.reset(new FileOutputBuffer(MappedFile.get(), FilePath, TempFilePath)); + if (Result) + MappedFile.release(); -error_code FileOutputBuffer::commit(int64_t NewSmallerSize) { + return std::error_code(); +} + +std::error_code FileOutputBuffer::commit(int64_t NewSmallerSize) { // Unmap buffer, letting OS flush dirty pages to file on disk. - void *Start = reinterpret_cast(BufferStart); - error_code EC = sys::fs::unmap_file_pages(Start, getBufferSize()); - if (EC) - return EC; - + Region.reset(); + // If requested, resize file as part of commit. if ( NewSmallerSize != -1 ) { - EC = sys::fs::resize_file(Twine(TempPath), NewSmallerSize); + std::error_code EC = sys::fs::resize_file(Twine(TempPath), NewSmallerSize); if (EC) return EC; } - + // Rename file to final name. return sys::fs::rename(Twine(TempPath), Twine(FinalPath)); } - - } // namespace -