LLVM  3.7.0
FileOutputBuffer.cpp
Go to the documentation of this file.
1 //===- FileOutputBuffer.cpp - File Output Buffer ----------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Utility for creating a in-memory buffer that will be written to a file.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/ADT/SmallString.h"
17 #include "llvm/Support/Errc.h"
18 #include <system_error>
19 
20 #if !defined(_MSC_VER) && !defined(__MINGW32__)
21 #include <unistd.h>
22 #else
23 #include <io.h>
24 #endif
25 
27 
28 namespace llvm {
29 FileOutputBuffer::FileOutputBuffer(std::unique_ptr<mapped_file_region> R,
30  StringRef Path, StringRef TmpPath)
31  : Region(std::move(R)), FinalPath(Path), TempPath(TmpPath) {}
32 
34  sys::fs::remove(Twine(TempPath));
35 }
36 
37 std::error_code
38 FileOutputBuffer::create(StringRef FilePath, size_t Size,
39  std::unique_ptr<FileOutputBuffer> &Result,
40  unsigned Flags) {
41  // If file already exists, it must be a regular file (to be mappable).
43  std::error_code EC = sys::fs::status(FilePath, Stat);
44  switch (Stat.type()) {
46  // If file does not exist, we'll create one.
47  break;
49  // If file is not currently writable, error out.
50  // FIXME: There is no sys::fs:: api for checking this.
51  // FIXME: In posix, you use the access() call to check this.
52  }
53  break;
54  default:
55  if (EC)
56  return EC;
57  else
59  }
60 
61  // Delete target file.
62  EC = sys::fs::remove(FilePath);
63  if (EC)
64  return EC;
65 
66  unsigned Mode = sys::fs::all_read | sys::fs::all_write;
67  // If requested, make the output file executable.
68  if (Flags & F_executable)
69  Mode |= sys::fs::all_exe;
70 
71  // Create new file in same directory but with random name.
72  SmallString<128> TempFilePath;
73  int FD;
74  EC = sys::fs::createUniqueFile(Twine(FilePath) + ".tmp%%%%%%%", FD,
75  TempFilePath, Mode);
76  if (EC)
77  return EC;
78 
79 #ifndef LLVM_ON_WIN32
80  // On Windows, CreateFileMapping (the mmap function on Windows)
81  // automatically extends the underlying file. We don't need to
82  // extend the file beforehand. _chsize (ftruncate on Windows) is
83  // pretty slow just like it writes specified amount of bytes,
84  // so we should avoid calling that.
85  EC = sys::fs::resize_file(FD, Size);
86  if (EC)
87  return EC;
88 #endif
89 
90  auto MappedFile = llvm::make_unique<mapped_file_region>(
91  FD, mapped_file_region::readwrite, Size, 0, EC);
92  int Ret = close(FD);
93  if (EC)
94  return EC;
95  if (Ret)
96  return std::error_code(errno, std::generic_category());
97 
98  Result.reset(
99  new FileOutputBuffer(std::move(MappedFile), FilePath, TempFilePath));
100 
101  return std::error_code();
102 }
103 
104 std::error_code FileOutputBuffer::commit() {
105  // Unmap buffer, letting OS flush dirty pages to file on disk.
106  Region.reset();
107 
108 
109  // Rename file to final name.
110  return sys::fs::rename(Twine(TempPath), Twine(FinalPath));
111 }
112 } // namespace
std::error_code createUniqueFile(const Twine &Model, int &ResultFD, SmallVectorImpl< char > &ResultPath, unsigned Mode=all_read|all_write)
Create a uniquely named file.
Definition: Path.cpp:681
std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
This class represents a memory mapped file.
Definition: FileSystem.h:627
file_status - Represents the result of a call to stat and friends.
Definition: FileSystem.h:138
~FileOutputBuffer()
If this object was previously committed, the destructor just deletes this object. ...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:79
FileOutputBuffer - This interface provides simple way to create an in-memory buffer which will be wri...
std::error_code make_error_code(BitcodeError E)
Definition: ReaderWriter.h:150
std::error_code commit()
Flushes the content of the buffer to its file and deallocates the buffer.
static std::error_code create(StringRef FilePath, size_t Size, std::unique_ptr< FileOutputBuffer > &Result, unsigned Flags=0)
Factory method to create an OutputBuffer object which manages a read/write buffer of the specified si...
std::error_code resize_file(int FD, uint64_t Size)
Resize path to size.
std::error_code rename(const Twine &from, const Twine &to)
Rename from to to.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40
std::error_code status(const Twine &path, file_status &result)
Get file status as if by POSIX stat().
file_type type() const
Definition: FileSystem.h:196