• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 //===----------------------------------------------------------------------===//
CleanupInstaller(const sys::fs::Path & pPath)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 
~CleanupInstaller()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 //===----------------------------------------------------------------------===//
ToolOutputFile(const sys::fs::Path & pPath,FileHandle::OpenMode pMode,FileHandle::Permission pPermission)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 
~ToolOutputFile()71 ToolOutputFile::~ToolOutputFile()
72 {
73   if (m_pFormattedOstream != NULL)
74     delete m_pFormattedOstream;
75   if (m_pFdOstream != NULL)
76     delete m_pFdOstream;
77 }
78 
keep()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.
os()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
formatted_os()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