LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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/OwningPtr.h"
16 #include "llvm/ADT/SmallVector.h"
19 
21 
22 namespace llvm {
23 FileOutputBuffer::FileOutputBuffer(mapped_file_region * R,
24  StringRef Path, StringRef TmpPath)
25  : Region(R)
26  , FinalPath(Path)
27  , TempPath(TmpPath) {
28 }
29 
31  bool Existed;
32  sys::fs::remove(Twine(TempPath), Existed);
33 }
34 
36  size_t Size,
38  unsigned Flags) {
39  // If file already exists, it must be a regular file (to be mappable).
41  error_code EC = sys::fs::status(FilePath, Stat);
42  switch (Stat.type()) {
44  // If file does not exist, we'll create one.
45  break;
47  // If file is not currently writable, error out.
48  // FIXME: There is no sys::fs:: api for checking this.
49  // FIXME: In posix, you use the access() call to check this.
50  }
51  break;
52  default:
53  if (EC)
54  return EC;
55  else
57  }
58 
59  // Delete target file.
60  bool Existed;
61  EC = sys::fs::remove(FilePath, Existed);
62  if (EC)
63  return EC;
64 
65  unsigned Mode = sys::fs::all_read | sys::fs::all_write;
66  // If requested, make the output file executable.
67  if (Flags & F_executable)
68  Mode |= sys::fs::all_exe;
69 
70  // Create new file in same directory but with random name.
71  SmallString<128> TempFilePath;
72  int FD;
73  EC = sys::fs::createUniqueFile(Twine(FilePath) + ".tmp%%%%%%%", FD,
74  TempFilePath, Mode);
75  if (EC)
76  return EC;
77 
79  FD, true, mapped_file_region::readwrite, Size, 0, EC));
80  if (EC)
81  return EC;
82 
83  Result.reset(new FileOutputBuffer(MappedFile.get(), FilePath, TempFilePath));
84  if (Result)
85  MappedFile.take();
86 
87  return error_code::success();
88 }
89 
90 error_code FileOutputBuffer::commit(int64_t NewSmallerSize) {
91  // Unmap buffer, letting OS flush dirty pages to file on disk.
92  Region.reset(0);
93 
94  // If requested, resize file as part of commit.
95  if ( NewSmallerSize != -1 ) {
96  error_code EC = sys::fs::resize_file(Twine(TempPath), NewSmallerSize);
97  if (EC)
98  return EC;
99  }
100 
101  // Rename file to final name.
102  return sys::fs::rename(Twine(TempPath), Twine(FinalPath));
103 }
104 } // namespace
error_code resize_file(const Twine &path, uint64_t size)
Resize path to size. File is resized as if by POSIX truncate().
error_code status(const Twine &path, file_status &result)
Get file status as if by POSIX stat().
void reset(T *P=0)
Definition: OwningPtr.h:51
A single entry single exit Region.
Definition: RegionInfo.h:202
T * get() const
Definition: OwningPtr.h:72
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:645
static error_code create(StringRef FilePath, size_t Size, OwningPtr< FileOutputBuffer > &Result, unsigned Flags=0)
error_code commit(int64_t NewSmallerSize=-1)
error_code remove(const Twine &path, bool &existed)
Remove path. Equivalent to POSIX remove().
static error_code success()
Definition: system_error.h:732
error_code rename(const Twine &from, const Twine &to)
Rename from to to. Files are renamed as if by POSIX rename().
file_type type() const
Definition: FileSystem.h:192
error_code make_error_code(errc _e)
Definition: system_error.h:782