Skip to content

Commit

Permalink
Do not remove a target file in FileOutputBuffer::create().
Browse files Browse the repository at this point in the history
FileOutputBuffer::create() attempts to remove a target file if the file
is a regular one, which results in an unexpected result in a failure
scenario.

If something goes wrong and the user of FileOutputBuffer decides to not
call commit(), it leaves nothing. An existing file is removed, and no
new file is created.

What we should do is to atomically replace an existing file with a new
file using rename(), so that it wouldn't remove an existing file without
creating a new one.

Differential Revision: https://reviews.llvm.org/D38283

llvm-svn: 314345
  • Loading branch information
rui314 committed Sep 27, 2017
1 parent fa1ae3e commit 23fa4de
Showing 1 changed file with 1 addition and 8 deletions.
9 changes: 1 addition & 8 deletions llvm/lib/Support/FileOutputBuffer.cpp
Expand Up @@ -65,13 +65,6 @@ FileOutputBuffer::create(StringRef FilePath, size_t Size, unsigned Flags) {
IsRegular = false;
}

if (IsRegular) {
// Delete target file.
EC = sys::fs::remove(FilePath);
if (EC)
return EC;
}

SmallString<128> TempFilePath;
int FD;
if (IsRegular) {
Expand Down Expand Up @@ -125,7 +118,7 @@ std::error_code FileOutputBuffer::commit() {

std::error_code EC;
if (IsRegular) {
// Rename file to final name.
// Atomically replace the existing file with the new one.
EC = sys::fs::rename(Twine(TempPath), Twine(FinalPath));
sys::DontRemoveFileOnSignal(TempPath);
} else {
Expand Down

0 comments on commit 23fa4de

Please sign in to comment.