xref: /freebsd/contrib/llvm-project/llvm/lib/Support/ToolOutputFile.cpp (revision 39ae24e3bf1c8e7d053d0249a6bc88f65eff6de1)
1  //===--- ToolOutputFile.cpp - Implement the ToolOutputFile class --------===//
2  //
3  // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4  // See https://llvm.org/LICENSE.txt for license information.
5  // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6  //
7  //===----------------------------------------------------------------------===//
8  //
9  // This implements the ToolOutputFile class.
10  //
11  //===----------------------------------------------------------------------===//
12  
13  #include "llvm/Support/ToolOutputFile.h"
14  #include "llvm/Support/FileSystem.h"
15  #include "llvm/Support/Signals.h"
16  using namespace llvm;
17  
18  static bool isStdout(StringRef Filename) { return Filename == "-"; }
19  
20  ToolOutputFile::CleanupInstaller::CleanupInstaller(StringRef Filename)
21      : Filename(std::string(Filename)), Keep(false) {
22    // Arrange for the file to be deleted if the process is killed.
23    if (!isStdout(Filename))
24      sys::RemoveFileOnSignal(Filename);
25  }
26  
27  ToolOutputFile::CleanupInstaller::~CleanupInstaller() {
28    if (isStdout(Filename))
29      return;
30  
31    // Delete the file if the client hasn't told us not to.
32    if (!Keep)
33      sys::fs::remove(Filename);
34  
35    // Ok, the file is successfully written and closed, or deleted. There's no
36    // further need to clean it up on signals.
37    sys::DontRemoveFileOnSignal(Filename);
38  }
39  
40  ToolOutputFile::ToolOutputFile(StringRef Filename, std::error_code &EC,
41                                 sys::fs::OpenFlags Flags)
42      : Installer(Filename) {
43    if (isStdout(Filename)) {
44      OS = &outs();
45      EC = std::error_code();
46      return;
47    }
48    OSHolder.emplace(Filename, EC, Flags);
49    OS = &*OSHolder;
50    // If open fails, no cleanup is needed.
51    if (EC)
52      Installer.Keep = true;
53  }
54  
55  ToolOutputFile::ToolOutputFile(StringRef Filename, int FD)
56      : Installer(Filename) {
57    OSHolder.emplace(FD, true);
58    OS = &*OSHolder;
59  }
60