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 23 using namespace mcld; 24 25 //===----------------------------------------------------------------------===// 26 // CleanupInstaller 27 //===----------------------------------------------------------------------===// 28 ToolOutputFile::CleanupInstaller::CleanupInstaller(const std::string& pName) 29 : Keep(false), m_Filename(pName) { 30 // Arrange for the file to be deleted if the process is killed. 31 if (m_Filename != "-") 32 llvm::sys::RemoveFileOnSignal(llvm::sys::Path(m_Filename)); 33 } 34 35 ToolOutputFile::CleanupInstaller::~CleanupInstaller() 36 { 37 // Delete the file if the client hasn't told us not to. 38 if (!Keep && m_Filename != "-") 39 llvm::sys::Path(m_Filename).eraseFromDisk(); 40 41 // Ok, the file is successfully written and closed, or deleted. There's no 42 // further need to clean it up on signals. 43 if (m_Filename != "-") 44 llvm::sys::DontRemoveFileOnSignal(llvm::sys::Path(m_Filename)); 45 } 46 47 //===----------------------------------------------------------------------===// 48 // ToolOutputFile 49 //===----------------------------------------------------------------------===// 50 ToolOutputFile::ToolOutputFile(const sys::fs::Path& pPath, 51 FileHandle::OpenMode pMode, 52 FileHandle::Permission pPermission) 53 : m_Installer(pPath.native()), 54 m_pMemoryArea(NULL), 55 m_pOStream(NULL), 56 m_pFOStream(NULL) { 57 58 if (!m_FileHandle.open(pPath, pMode, pPermission)) { 59 // If open fails, no clean-up is needed. 60 m_Installer.Keep = true; 61 fatal(diag::err_cannot_open_output_file) 62 << pPath 63 << sys::strerror(m_FileHandle.error()); 64 return; 65 } 66 67 m_pMemoryArea = new MemoryArea(m_FileHandle); 68 m_pOStream = new raw_mem_ostream(*m_pMemoryArea); 69 } 70 71 ToolOutputFile::~ToolOutputFile() 72 { 73 delete m_pFOStream; 74 delete m_pOStream; 75 delete m_pMemoryArea; 76 } 77 78 void ToolOutputFile::keep() 79 { 80 m_Installer.Keep = true; 81 } 82 83 /// mem_os - Return the contained raw_mem_ostream. 84 raw_mem_ostream& ToolOutputFile::mem_os() 85 { 86 assert(NULL != m_pOStream); 87 return *m_pOStream; 88 } 89 90 /// formatted_os - Return the containeed formatted_raw_ostream. 91 /// Since formatted_os is rarely used, we lazily initialize it. 92 llvm::formatted_raw_ostream& ToolOutputFile::formatted_os() 93 { 94 if (NULL == m_pFOStream) { 95 assert(NULL != m_pOStream); 96 m_pFOStream = new llvm::formatted_raw_ostream(*m_pOStream); 97 } 98 99 return *m_pFOStream; 100 } 101 102 /// memory - Return the contained MemoryArea. 103 MemoryArea& ToolOutputFile::memory() 104 { 105 assert(NULL != m_pOStream); 106 return m_pOStream->getMemoryArea(); 107 } 108 109