Home | History | Annotate | Download | only in Support
      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