| //===- 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/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; |
| } |