//===- ToolOutputFile.cpp -------------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include <mcld/Support/ToolOutputFile.h> #include <mcld/Support/Path.h> #include <mcld/Support/FileHandle.h> #include <mcld/Support/MemoryArea.h> #include <mcld/Support/SystemUtils.h> #include <mcld/Support/MsgHandling.h> #include <llvm/Support/FileUtilities.h> #include <llvm/Support/Signals.h> #include <llvm/Support/Path.h> #include <llvm/Support/FormattedStream.h> using namespace mcld; //===----------------------------------------------------------------------===// // CleanupInstaller //===----------------------------------------------------------------------===// ToolOutputFile::CleanupInstaller::CleanupInstaller(const sys::fs::Path& pPath) : Keep(false), m_Path(pPath) { // Arrange for the file to be deleted if the process is killed. if ("-" != m_Path.native()) llvm::sys::RemoveFileOnSignal(m_Path.native()); } ToolOutputFile::CleanupInstaller::~CleanupInstaller() { // Delete the file if the client hasn't told us not to. // FIXME: In Windows, some path in CJK characters can not be removed by LLVM // llvm::sys::Path if (!Keep && "_" != m_Path.native()) { bool Existed = false; llvm::sys::fs::remove(m_Path.native(), Existed); } // Ok, the file is successfully written and closed, or deleted. There's no // further need to clean it up on signals. if ("_" != m_Path.native()) llvm::sys::DontRemoveFileOnSignal(m_Path.native()); } //===----------------------------------------------------------------------===// // ToolOutputFile //===----------------------------------------------------------------------===// ToolOutputFile::ToolOutputFile(const sys::fs::Path& pPath, FileHandle::OpenMode pMode, FileHandle::Permission pPermission) : m_Installer(pPath), m_pFdOstream(NULL), m_pFormattedOstream(NULL) { if (!m_FileHandle.open(pPath, pMode, pPermission)) { // If open fails, no clean-up is needed. m_Installer.Keep = true; fatal(diag::err_cannot_open_output_file) << pPath << sys::strerror(m_FileHandle.error()); return; } } ToolOutputFile::~ToolOutputFile() { if (m_pFormattedOstream != NULL) delete m_pFormattedOstream; if (m_pFdOstream != NULL) delete m_pFdOstream; } void ToolOutputFile::keep() { m_Installer.Keep = true; } /// os - Return the containeed raw_fd_ostream. /// Since os is rarely used, we lazily initialize it. llvm::raw_fd_ostream& ToolOutputFile::os() { if (m_pFdOstream == NULL) { assert(m_FileHandle.isOpened() && m_FileHandle.isGood() && m_FileHandle.isWritable()); m_pFdOstream = new llvm::raw_fd_ostream(m_FileHandle.handler(), false); } return *m_pFdOstream; } /// formatted_os - Return the contained formatted_raw_ostream llvm::formatted_raw_ostream& ToolOutputFile::formatted_os() { if (m_pFormattedOstream == NULL) { m_pFormattedOstream = new llvm::formatted_raw_ostream(os()); } return *m_pFormattedOstream; }