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