Index: tools/dsymutil/dsymutil.cpp =================================================================== --- tools/dsymutil/dsymutil.cpp +++ tools/dsymutil/dsymutil.cpp @@ -181,43 +181,7 @@ return true; } -static std::error_code getUniqueFile(const llvm::Twine &Model, int &ResultFD, - llvm::SmallVectorImpl &ResultPath) { - // If in NoOutput mode, use the createUniqueFile variant that - // doesn't open the file but still generates a somewhat unique - // name. In the real usage scenario, we'll want to ensure that the - // file is trully unique, and creating it is the only way to achieve - // that. - if (NoOutput) - return llvm::sys::fs::createUniqueFile(Model, ResultPath); - return llvm::sys::fs::createUniqueFile(Model, ResultFD, ResultPath); -} - -static std::string getOutputFileName(llvm::StringRef InputFile, - bool TempFile = false) { - if (TempFile) { - llvm::SmallString<128> TmpFile; - llvm::sys::path::system_temp_directory(true, TmpFile); - llvm::StringRef Basename = - OutputFileOpt.empty() ? InputFile : llvm::StringRef(OutputFileOpt); - llvm::sys::path::append(TmpFile, llvm::sys::path::filename(Basename)); - - int FD; - llvm::SmallString<128> UniqueFile; - if (auto EC = getUniqueFile(TmpFile + ".tmp%%%%%.dwarf", FD, UniqueFile)) { - llvm::errs() << "error: failed to create temporary outfile '" - << TmpFile << "': " << EC.message() << '\n'; - return ""; - } - llvm::sys::RemoveFileOnSignal(UniqueFile); - if (!NoOutput) { - // Close the file immediately. We know it is unique. It will be - // reopened and written to later. - llvm::raw_fd_ostream CloseImmediately(FD, true /* shouldClose */, true); - } - return UniqueFile.str(); - } - +static std::string getOutputFileName(llvm::StringRef InputFile) { if (FlatOut) { // If a flat dSYM has been requested, things are pretty simple. if (OutputFileOpt.empty()) { @@ -250,9 +214,16 @@ return BundleDir.str(); } +static std::vector TempFileStore; void llvm::dsymutil::exitDsymutil(int ExitStatus) { // Cleanup temporary files. - llvm::sys::RunInterruptHandlers(); + for (sys::fs::TempFile &Tmp : TempFileStore) { + if (Error E = Tmp.discard()) { + ExitStatus = 1; + consumeError(std::move(E)); + } + } + exit(ExitStatus); } @@ -342,6 +313,10 @@ // If there is more than one link to execute, we need to generate // temporary files. + llvm::SmallString<128> TmpModel; + llvm::sys::path::system_temp_directory(true, TmpModel); + llvm::sys::path::append(TmpModel, "dysym.tmp%%%%%.dwarf"); + bool NeedsTempFiles = !DumpDebugMap && (*DebugMapPtrsOrErr).size() != 1; llvm::SmallVector TempFiles; for (auto &Map : *DebugMapPtrsOrErr) { @@ -356,18 +331,29 @@ << MachOUtils::getArchName(Map->getTriple().getArchName()) << ")\n"; - std::string OutputFile = getOutputFileName(InputFile, NeedsTempFiles); - - auto LinkLambda = [OutputFile, Options, &Map]() { - if (OutputFile.empty()) + std::string OutputFile = getOutputFileName(InputFile); + std::unique_ptr OS; + if (NeedsTempFiles) { + Expected T = sys::fs::TempFile::create(TmpModel); + if (!T) { + errs() << toString(T.takeError()); exitDsymutil(1); + } + OS = make_unique(T->FD, /*shouldClose*/ false); + OutputFile = T->TmpName; + TempFileStore.push_back(std::move(*T)); + } else { std::error_code EC; - raw_fd_ostream OS(NoOutput ? "-" : OutputFile, EC, sys::fs::F_None); + OS = make_unique(NoOutput ? "-" : OutputFile, EC, + sys::fs::F_None); if (EC) { errs() << OutputFile << ": " << EC.message(); exitDsymutil(1); } - if (!linkDwarf(OS, *Map, Options)) + } + + auto LinkLambda = [&]() { + if (!linkDwarf(*OS, *Map, Options)) exitDsymutil(1); };