xref: /freebsd-src/contrib/llvm-project/llvm/lib/Support/Process.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-- Process.cpp - Implement OS Process Concept --------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric //  This file implements the operating system Process concept.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "llvm/Support/Process.h"
140b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
150b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h"
160b57cec5SDimitry Andric #include "llvm/Config/config.h"
1713138422SDimitry Andric #include "llvm/Config/llvm-config.h"
1813138422SDimitry Andric #include "llvm/Support/CrashRecoveryContext.h"
190b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h"
200b57cec5SDimitry Andric #include "llvm/Support/Path.h"
210b57cec5SDimitry Andric #include "llvm/Support/Program.h"
220b57cec5SDimitry Andric 
23bdd1243dSDimitry Andric #include <optional>
24e8d8bef9SDimitry Andric #include <stdlib.h> // for _Exit
25e8d8bef9SDimitry Andric 
260b57cec5SDimitry Andric using namespace llvm;
270b57cec5SDimitry Andric using namespace sys;
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
300b57cec5SDimitry Andric //=== WARNING: Implementation here must contain only TRULY operating system
310b57cec5SDimitry Andric //===          independent code.
320b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
330b57cec5SDimitry Andric 
34bdd1243dSDimitry Andric std::optional<std::string>
35e8d8bef9SDimitry Andric Process::FindInEnvPath(StringRef EnvName, StringRef FileName, char Separator) {
36e8d8bef9SDimitry Andric   return FindInEnvPath(EnvName, FileName, {}, Separator);
370b57cec5SDimitry Andric }
380b57cec5SDimitry Andric 
39bdd1243dSDimitry Andric std::optional<std::string>
40bdd1243dSDimitry Andric Process::FindInEnvPath(StringRef EnvName, StringRef FileName,
41bdd1243dSDimitry Andric                        ArrayRef<std::string> IgnoreList, char Separator) {
420b57cec5SDimitry Andric   assert(!path::is_absolute(FileName));
43bdd1243dSDimitry Andric   std::optional<std::string> FoundPath;
44bdd1243dSDimitry Andric   std::optional<std::string> OptPath = Process::GetEnv(EnvName);
4581ad6265SDimitry Andric   if (!OptPath)
460b57cec5SDimitry Andric     return FoundPath;
470b57cec5SDimitry Andric 
48e8d8bef9SDimitry Andric   const char EnvPathSeparatorStr[] = {Separator, '\0'};
490b57cec5SDimitry Andric   SmallVector<StringRef, 8> Dirs;
50bdd1243dSDimitry Andric   SplitString(*OptPath, Dirs, EnvPathSeparatorStr);
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric   for (StringRef Dir : Dirs) {
530b57cec5SDimitry Andric     if (Dir.empty())
540b57cec5SDimitry Andric       continue;
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric     if (any_of(IgnoreList, [&](StringRef S) { return fs::equivalent(S, Dir); }))
570b57cec5SDimitry Andric       continue;
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric     SmallString<128> FilePath(Dir);
600b57cec5SDimitry Andric     path::append(FilePath, FileName);
610b57cec5SDimitry Andric     if (fs::exists(Twine(FilePath))) {
627a6dacacSDimitry Andric       FoundPath = std::string(FilePath);
630b57cec5SDimitry Andric       break;
640b57cec5SDimitry Andric     }
650b57cec5SDimitry Andric   }
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric   return FoundPath;
680b57cec5SDimitry Andric }
690b57cec5SDimitry Andric 
70*0fca6ea1SDimitry Andric // clang-format off
710b57cec5SDimitry Andric #define COLOR(FGBG, CODE, BOLD) "\033[0;" BOLD FGBG CODE "m"
720b57cec5SDimitry Andric 
73*0fca6ea1SDimitry Andric #define ALLCOLORS(FGBG, BRIGHT, BOLD) \
74*0fca6ea1SDimitry Andric   {                           \
750b57cec5SDimitry Andric     COLOR(FGBG, "0", BOLD),   \
760b57cec5SDimitry Andric     COLOR(FGBG, "1", BOLD),   \
770b57cec5SDimitry Andric     COLOR(FGBG, "2", BOLD),   \
780b57cec5SDimitry Andric     COLOR(FGBG, "3", BOLD),   \
790b57cec5SDimitry Andric     COLOR(FGBG, "4", BOLD),   \
800b57cec5SDimitry Andric     COLOR(FGBG, "5", BOLD),   \
810b57cec5SDimitry Andric     COLOR(FGBG, "6", BOLD),   \
82*0fca6ea1SDimitry Andric     COLOR(FGBG, "7", BOLD),   \
83*0fca6ea1SDimitry Andric     COLOR(BRIGHT, "0", BOLD), \
84*0fca6ea1SDimitry Andric     COLOR(BRIGHT, "1", BOLD), \
85*0fca6ea1SDimitry Andric     COLOR(BRIGHT, "2", BOLD), \
86*0fca6ea1SDimitry Andric     COLOR(BRIGHT, "3", BOLD), \
87*0fca6ea1SDimitry Andric     COLOR(BRIGHT, "4", BOLD), \
88*0fca6ea1SDimitry Andric     COLOR(BRIGHT, "5", BOLD), \
89*0fca6ea1SDimitry Andric     COLOR(BRIGHT, "6", BOLD), \
90*0fca6ea1SDimitry Andric     COLOR(BRIGHT, "7", BOLD), \
910b57cec5SDimitry Andric   }
920b57cec5SDimitry Andric 
93*0fca6ea1SDimitry Andric //                           bg
94*0fca6ea1SDimitry Andric //                           |  bold
95*0fca6ea1SDimitry Andric //                           |  |
96*0fca6ea1SDimitry Andric //                           |  |   codes
97*0fca6ea1SDimitry Andric //                           |  |   |
98*0fca6ea1SDimitry Andric //                           |  |   |
99*0fca6ea1SDimitry Andric static const char colorcodes[2][2][16][11] = {
100*0fca6ea1SDimitry Andric     { ALLCOLORS("3", "9", ""), ALLCOLORS("3", "9", "1;"),},
101*0fca6ea1SDimitry Andric     { ALLCOLORS("4", "10", ""), ALLCOLORS("4", "10", "1;")}
1020b57cec5SDimitry Andric };
103*0fca6ea1SDimitry Andric // clang-format on
1040b57cec5SDimitry Andric 
1050b57cec5SDimitry Andric // A CMake option controls wheter we emit core dumps by default. An application
1060b57cec5SDimitry Andric // may disable core dumps by calling Process::PreventCoreFiles().
1070b57cec5SDimitry Andric static bool coreFilesPrevented = !LLVM_ENABLE_CRASH_DUMPS;
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric bool Process::AreCoreFilesPrevented() { return coreFilesPrevented; }
1100b57cec5SDimitry Andric 
111349cc55cSDimitry Andric [[noreturn]] void Process::Exit(int RetCode, bool NoCleanup) {
11213138422SDimitry Andric   if (CrashRecoveryContext *CRC = CrashRecoveryContext::GetCurrent())
11313138422SDimitry Andric     CRC->HandleExit(RetCode);
114e8d8bef9SDimitry Andric 
115e8d8bef9SDimitry Andric   if (NoCleanup)
116fe6060f1SDimitry Andric     ExitNoCleanup(RetCode);
117e8d8bef9SDimitry Andric   else
11813138422SDimitry Andric     ::exit(RetCode);
11913138422SDimitry Andric }
12013138422SDimitry Andric 
1210b57cec5SDimitry Andric // Include the platform-specific parts of this class.
1220b57cec5SDimitry Andric #ifdef LLVM_ON_UNIX
1230b57cec5SDimitry Andric #include "Unix/Process.inc"
1240b57cec5SDimitry Andric #endif
1250b57cec5SDimitry Andric #ifdef _WIN32
1260b57cec5SDimitry Andric #include "Windows/Process.inc"
1270b57cec5SDimitry Andric #endif
128