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 15 #include <mcld/Support/SystemUtils.h> 16 #include <mcld/Support/MsgHandling.h> 17 18 #include <llvm/Support/FileUtilities.h> 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 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(m_Path.native()); 33 } 34 35 ToolOutputFile::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 bool Existed = false; 42 llvm::sys::fs::remove(m_Path.native(), Existed); 43 } 44 45 // Ok, the file is successfully written and closed, or deleted. There's no 46 // further need to clean it up on signals. 47 if ("_" != m_Path.native()) 48 llvm::sys::DontRemoveFileOnSignal(m_Path.native()); 49 } 50 51 //===----------------------------------------------------------------------===// 52 // ToolOutputFile 53 //===----------------------------------------------------------------------===// 54 ToolOutputFile::ToolOutputFile(const sys::fs::Path& pPath, 55 FileHandle::OpenMode pMode, 56 FileHandle::Permission pPermission) 57 : m_Installer(pPath), 58 m_pFdOstream(NULL), 59 m_pFormattedOstream(NULL) { 60 61 if (!m_FileHandle.open(pPath, pMode, pPermission)) { 62 // If open fails, no clean-up is needed. 63 m_Installer.Keep = true; 64 fatal(diag::err_cannot_open_output_file) 65 << pPath 66 << sys::strerror(m_FileHandle.error()); 67 return; 68 } 69 } 70 71 ToolOutputFile::~ToolOutputFile() 72 { 73 if (m_pFormattedOstream != NULL) 74 delete m_pFormattedOstream; 75 if (m_pFdOstream != NULL) 76 delete m_pFdOstream; 77 } 78 79 void ToolOutputFile::keep() 80 { 81 m_Installer.Keep = true; 82 } 83 84 /// os - Return the containeed raw_fd_ostream. 85 /// Since os is rarely used, we lazily initialize it. 86 llvm::raw_fd_ostream& ToolOutputFile::os() 87 { 88 if (m_pFdOstream == NULL) { 89 assert(m_FileHandle.isOpened() && 90 m_FileHandle.isGood() && 91 m_FileHandle.isWritable()); 92 m_pFdOstream = new llvm::raw_fd_ostream(m_FileHandle.handler(), false); 93 } 94 return *m_pFdOstream; 95 } 96 97 /// formatted_os - Return the contained formatted_raw_ostream 98 llvm::formatted_raw_ostream& ToolOutputFile::formatted_os() 99 { 100 if (m_pFormattedOstream == NULL) { 101 m_pFormattedOstream = new llvm::formatted_raw_ostream(os()); 102 } 103 return *m_pFormattedOstream; 104 } 105