diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2016-05-09 13:31:11 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2016-05-09 13:31:11 +0000 |
commit | 484983f453c1c29725a02262124beea52a7bbd0b (patch) | |
tree | 6b2027092a99f8e3086bad284b9fad0bd9eab41b /llvm/tools/llvm-ar/llvm-ar.cpp | |
parent | af742d51ad622b158f71523369fc8998b35ffb3c (diff) | |
download | bcm5719-llvm-484983f453c1c29725a02262124beea52a7bbd0b.tar.gz bcm5719-llvm-484983f453c1c29725a02262124beea52a7bbd0b.zip |
Fix bug where temporary file would be left behind every time an archive was updated.
When updating an existing archive, llvm-ar opens the old archive into a
`MemoryBuffer`, does its thing, and writes the results to a temporary
file. That file is then renamed to the original archive filename, thus
replacing it with the updated contents. However, on Windows at least,
what would happen is that the `MemoryBuffer` for the old archive would
actually be an mmap'ed view of the file, so when it came time to do the
rename via Win32's `ReplaceFile`, it would succeed but would be unable
to fully replace the file since there would still be a handle open on
it; instead, the old version got renamed to a random temporary name and
left behind.
Patch by Cameron!
llvm-svn: 268916
Diffstat (limited to 'llvm/tools/llvm-ar/llvm-ar.cpp')
-rw-r--r-- | llvm/tools/llvm-ar/llvm-ar.cpp | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/llvm/tools/llvm-ar/llvm-ar.cpp b/llvm/tools/llvm-ar/llvm-ar.cpp index 45f778b9af6..375b34d9b41 100644 --- a/llvm/tools/llvm-ar/llvm-ar.cpp +++ b/llvm/tools/llvm-ar/llvm-ar.cpp @@ -576,7 +576,9 @@ computeNewArchiveMembers(ArchiveOperation Operation, } static void -performWriteOperation(ArchiveOperation Operation, object::Archive *OldArchive, +performWriteOperation(ArchiveOperation Operation, + object::Archive *OldArchive, + std::unique_ptr<MemoryBuffer> OldArchiveBuf, std::vector<NewArchiveIterator> *NewMembersP) { object::Archive::Kind Kind; switch (FormatOpt) { @@ -599,14 +601,16 @@ performWriteOperation(ArchiveOperation Operation, object::Archive *OldArchive, } if (NewMembersP) { std::pair<StringRef, std::error_code> Result = writeArchive( - ArchiveName, *NewMembersP, Symtab, Kind, Deterministic, Thin); + ArchiveName, *NewMembersP, Symtab, Kind, Deterministic, Thin, + std::move(OldArchiveBuf)); failIfError(Result.second, Result.first); return; } std::vector<NewArchiveIterator> NewMembers = computeNewArchiveMembers(Operation, OldArchive); auto Result = - writeArchive(ArchiveName, NewMembers, Symtab, Kind, Deterministic, Thin); + writeArchive(ArchiveName, NewMembers, Symtab, Kind, Deterministic, Thin, + std::move(OldArchiveBuf)); failIfError(Result.second, Result.first); } @@ -620,11 +624,12 @@ static void createSymbolTable(object::Archive *OldArchive) { if (OldArchive->hasSymbolTable()) return; - performWriteOperation(CreateSymTab, OldArchive, nullptr); + performWriteOperation(CreateSymTab, OldArchive, nullptr, nullptr); } static void performOperation(ArchiveOperation Operation, object::Archive *OldArchive, + std::unique_ptr<MemoryBuffer> OldArchiveBuf, std::vector<NewArchiveIterator> *NewMembers) { switch (Operation) { case Print: @@ -637,7 +642,8 @@ static void performOperation(ArchiveOperation Operation, case Move: case QuickAppend: case ReplaceOrInsert: - performWriteOperation(Operation, OldArchive, NewMembers); + performWriteOperation(Operation, OldArchive, std::move(OldArchiveBuf), + NewMembers); return; case CreateSymTab: createSymbolTable(OldArchive); @@ -659,7 +665,7 @@ static int performOperation(ArchiveOperation Operation, object::Archive Archive(Buf.get()->getMemBufferRef(), EC); failIfError(EC, "error loading '" + ArchiveName + "': " + EC.message() + "!"); - performOperation(Operation, &Archive, NewMembers); + performOperation(Operation, &Archive, std::move(Buf.get()), NewMembers); return 0; } @@ -674,7 +680,7 @@ static int performOperation(ArchiveOperation Operation, } } - performOperation(Operation, nullptr, NewMembers); + performOperation(Operation, nullptr, nullptr, NewMembers); return 0; } |