Mercurial > hg > Members > tobaru > cbc > CbC_llvm
comparison lib/Support/FileOutputBuffer.cpp @ 97:b0dd3743370f
LLVM 3.8
author | Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 14 Oct 2015 19:39:58 +0900 |
parents | afa8332a0e37 |
children | 1172e4bd9c6f |
comparison
equal
deleted
inserted
replaced
94:d52ff4b80465 | 97:b0dd3743370f |
---|---|
9 // | 9 // |
10 // Utility for creating a in-memory buffer that will be written to a file. | 10 // Utility for creating a in-memory buffer that will be written to a file. |
11 // | 11 // |
12 //===----------------------------------------------------------------------===// | 12 //===----------------------------------------------------------------------===// |
13 | 13 |
14 #include "llvm/Support/FileOutputBuffer.h" | |
15 #include "llvm/ADT/STLExtras.h" | |
16 #include "llvm/ADT/SmallString.h" | |
14 #include "llvm/Support/Errc.h" | 17 #include "llvm/Support/Errc.h" |
15 #include "llvm/ADT/STLExtras.h" | 18 #include "llvm/Support/Signals.h" |
16 #include "llvm/ADT/SmallVector.h" | |
17 #include "llvm/Support/FileOutputBuffer.h" | |
18 #include "llvm/Support/raw_ostream.h" | |
19 #include <system_error> | 19 #include <system_error> |
20 | 20 |
21 #if !defined(_MSC_VER) && !defined(__MINGW32__) | 21 #if !defined(_MSC_VER) && !defined(__MINGW32__) |
22 #include <unistd.h> | 22 #include <unistd.h> |
23 #else | 23 #else |
33 | 33 |
34 FileOutputBuffer::~FileOutputBuffer() { | 34 FileOutputBuffer::~FileOutputBuffer() { |
35 sys::fs::remove(Twine(TempPath)); | 35 sys::fs::remove(Twine(TempPath)); |
36 } | 36 } |
37 | 37 |
38 std::error_code | 38 ErrorOr<std::unique_ptr<FileOutputBuffer>> |
39 FileOutputBuffer::create(StringRef FilePath, size_t Size, | 39 FileOutputBuffer::create(StringRef FilePath, size_t Size, unsigned Flags) { |
40 std::unique_ptr<FileOutputBuffer> &Result, | |
41 unsigned Flags) { | |
42 // If file already exists, it must be a regular file (to be mappable). | 40 // If file already exists, it must be a regular file (to be mappable). |
43 sys::fs::file_status Stat; | 41 sys::fs::file_status Stat; |
44 std::error_code EC = sys::fs::status(FilePath, Stat); | 42 std::error_code EC = sys::fs::status(FilePath, Stat); |
45 switch (Stat.type()) { | 43 switch (Stat.type()) { |
46 case sys::fs::file_type::file_not_found: | 44 case sys::fs::file_type::file_not_found: |
75 EC = sys::fs::createUniqueFile(Twine(FilePath) + ".tmp%%%%%%%", FD, | 73 EC = sys::fs::createUniqueFile(Twine(FilePath) + ".tmp%%%%%%%", FD, |
76 TempFilePath, Mode); | 74 TempFilePath, Mode); |
77 if (EC) | 75 if (EC) |
78 return EC; | 76 return EC; |
79 | 77 |
78 sys::RemoveFileOnSignal(TempFilePath); | |
79 | |
80 #ifndef LLVM_ON_WIN32 | |
81 // On Windows, CreateFileMapping (the mmap function on Windows) | |
82 // automatically extends the underlying file. We don't need to | |
83 // extend the file beforehand. _chsize (ftruncate on Windows) is | |
84 // pretty slow just like it writes specified amount of bytes, | |
85 // so we should avoid calling that. | |
80 EC = sys::fs::resize_file(FD, Size); | 86 EC = sys::fs::resize_file(FD, Size); |
81 if (EC) | 87 if (EC) |
82 return EC; | 88 return EC; |
89 #endif | |
83 | 90 |
84 auto MappedFile = llvm::make_unique<mapped_file_region>( | 91 auto MappedFile = llvm::make_unique<mapped_file_region>( |
85 FD, mapped_file_region::readwrite, Size, 0, EC); | 92 FD, mapped_file_region::readwrite, Size, 0, EC); |
86 int Ret = close(FD); | 93 int Ret = close(FD); |
87 if (EC) | 94 if (EC) |
88 return EC; | 95 return EC; |
89 if (Ret) | 96 if (Ret) |
90 return std::error_code(errno, std::generic_category()); | 97 return std::error_code(errno, std::generic_category()); |
91 | 98 |
92 Result.reset( | 99 std::unique_ptr<FileOutputBuffer> Buf( |
93 new FileOutputBuffer(std::move(MappedFile), FilePath, TempFilePath)); | 100 new FileOutputBuffer(std::move(MappedFile), FilePath, TempFilePath)); |
94 | 101 return std::move(Buf); |
95 return std::error_code(); | |
96 } | 102 } |
97 | 103 |
98 std::error_code FileOutputBuffer::commit() { | 104 std::error_code FileOutputBuffer::commit() { |
99 // Unmap buffer, letting OS flush dirty pages to file on disk. | 105 // Unmap buffer, letting OS flush dirty pages to file on disk. |
100 Region.reset(); | 106 Region.reset(); |
101 | 107 |
102 | 108 |
103 // Rename file to final name. | 109 // Rename file to final name. |
104 return sys::fs::rename(Twine(TempPath), Twine(FinalPath)); | 110 std::error_code EC = sys::fs::rename(Twine(TempPath), Twine(FinalPath)); |
111 sys::DontRemoveFileOnSignal(TempPath); | |
112 return EC; | |
105 } | 113 } |
106 } // namespace | 114 } // namespace |