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 //===----------------------------------------------------------------------===//
CleanupInstaller(const std::string & pName)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
~CleanupInstaller()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 //===----------------------------------------------------------------------===//
ToolOutputFile(const sys::fs::Path & pPath,FileHandle::OpenMode pMode,FileHandle::Permission pPermission)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
~ToolOutputFile()71 ToolOutputFile::~ToolOutputFile()
72 {
73 delete m_pFOStream;
74 delete m_pOStream;
75 delete m_pMemoryArea;
76 }
77
keep()78 void ToolOutputFile::keep()
79 {
80 m_Installer.Keep = true;
81 }
82
83 /// mem_os - Return the contained raw_mem_ostream.
mem_os()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.
formatted_os()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.
memory()103 MemoryArea& ToolOutputFile::memory()
104 {
105 assert(NULL != m_pOStream);
106 return m_pOStream->getMemoryArea();
107 }
108
109