1//===- ToolOutputFile.cpp -------------------------------------------------===// 2// 3// The MCLinker Project 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9#include <mcld/Support/ToolOutputFile.h> 10 11#include <mcld/Support/Path.h> 12#include <mcld/Support/FileHandle.h> 13#include <mcld/Support/MemoryArea.h> 14#include <mcld/Support/raw_mem_ostream.h> 15 16#include <mcld/Support/SystemUtils.h> 17#include <mcld/Support/MsgHandling.h> 18 19#include <llvm/Support/Signals.h> 20#include <llvm/Support/Path.h> 21#include <llvm/Support/FormattedStream.h> 22 23using namespace mcld; 24 25//===----------------------------------------------------------------------===// 26// CleanupInstaller 27//===----------------------------------------------------------------------===// 28ToolOutputFile::CleanupInstaller::CleanupInstaller(const sys::fs::Path& pPath) 29 : Keep(false), m_Path(pPath) { 30 // Arrange for the file to be deleted if the process is killed. 31 if ("-" != m_Path.native()) 32 llvm::sys::RemoveFileOnSignal(llvm::sys::Path(m_Path.native())); 33} 34 35ToolOutputFile::CleanupInstaller::~CleanupInstaller() 36{ 37 // Delete the file if the client hasn't told us not to. 38 // FIXME: In Windows, some path in CJK characters can not be removed by LLVM 39 // llvm::sys::Path 40 if (!Keep && "_" != m_Path.native()) 41 llvm::sys::Path(m_Path.native()).eraseFromDisk(); 42 43 // Ok, the file is successfully written and closed, or deleted. There's no 44 // further need to clean it up on signals. 45 if ("_" != m_Path.native()) 46 llvm::sys::DontRemoveFileOnSignal(llvm::sys::Path(m_Path.native())); 47} 48 49//===----------------------------------------------------------------------===// 50// ToolOutputFile 51//===----------------------------------------------------------------------===// 52ToolOutputFile::ToolOutputFile(const sys::fs::Path& pPath, 53 FileHandle::OpenMode pMode, 54 FileHandle::Permission pPermission) 55 : m_Installer(pPath), 56 m_pMemoryArea(NULL), 57 m_pOStream(NULL), 58 m_pFOStream(NULL) { 59 60 if (!m_FileHandle.open(pPath, pMode, pPermission)) { 61 // If open fails, no clean-up is needed. 62 m_Installer.Keep = true; 63 fatal(diag::err_cannot_open_output_file) 64 << pPath 65 << sys::strerror(m_FileHandle.error()); 66 return; 67 } 68 69 m_pMemoryArea = new MemoryArea(m_FileHandle); 70 m_pOStream = new raw_mem_ostream(*m_pMemoryArea); 71} 72 73ToolOutputFile::~ToolOutputFile() 74{ 75 delete m_pFOStream; 76 delete m_pOStream; 77 delete m_pMemoryArea; 78} 79 80void ToolOutputFile::keep() 81{ 82 m_Installer.Keep = true; 83} 84 85/// mem_os - Return the contained raw_mem_ostream. 86raw_mem_ostream& ToolOutputFile::mem_os() 87{ 88 assert(NULL != m_pOStream); 89 return *m_pOStream; 90} 91 92/// formatted_os - Return the containeed formatted_raw_ostream. 93/// Since formatted_os is rarely used, we lazily initialize it. 94llvm::formatted_raw_ostream& ToolOutputFile::formatted_os() 95{ 96 if (NULL == m_pFOStream) { 97 assert(NULL != m_pOStream); 98 m_pFOStream = new llvm::formatted_raw_ostream(*m_pOStream); 99 } 100 101 return *m_pFOStream; 102} 103 104/// memory - Return the contained MemoryArea. 105MemoryArea& ToolOutputFile::memory() 106{ 107 assert(NULL != m_pOStream); 108 return m_pOStream->getMemoryArea(); 109} 110 111