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>
FindInEnvPath(StringRef EnvName,StringRef FileName,char Separator)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>
FindInEnvPath(StringRef EnvName,StringRef FileName,ArrayRef<std::string> IgnoreList,char Separator)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))) {
62*a58f00eaSDimitry Andric       FoundPath = std::string(FilePath);
630b57cec5SDimitry Andric       break;
640b57cec5SDimitry Andric     }
650b57cec5SDimitry Andric   }
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric   return FoundPath;
680b57cec5SDimitry Andric }
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric #define COLOR(FGBG, CODE, BOLD) "\033[0;" BOLD FGBG CODE "m"
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric #define ALLCOLORS(FGBG,BOLD) {\
740b57cec5SDimitry Andric     COLOR(FGBG, "0", BOLD),\
750b57cec5SDimitry Andric     COLOR(FGBG, "1", BOLD),\
760b57cec5SDimitry Andric     COLOR(FGBG, "2", BOLD),\
770b57cec5SDimitry Andric     COLOR(FGBG, "3", BOLD),\
780b57cec5SDimitry Andric     COLOR(FGBG, "4", BOLD),\
790b57cec5SDimitry Andric     COLOR(FGBG, "5", BOLD),\
800b57cec5SDimitry Andric     COLOR(FGBG, "6", BOLD),\
810b57cec5SDimitry Andric     COLOR(FGBG, "7", BOLD)\
820b57cec5SDimitry Andric   }
830b57cec5SDimitry Andric 
840b57cec5SDimitry Andric static const char colorcodes[2][2][8][10] = {
850b57cec5SDimitry Andric  { ALLCOLORS("3",""), ALLCOLORS("3","1;") },
860b57cec5SDimitry Andric  { ALLCOLORS("4",""), ALLCOLORS("4","1;") }
870b57cec5SDimitry Andric };
880b57cec5SDimitry Andric 
890b57cec5SDimitry Andric // A CMake option controls wheter we emit core dumps by default. An application
900b57cec5SDimitry Andric // may disable core dumps by calling Process::PreventCoreFiles().
910b57cec5SDimitry Andric static bool coreFilesPrevented = !LLVM_ENABLE_CRASH_DUMPS;
920b57cec5SDimitry Andric 
AreCoreFilesPrevented()930b57cec5SDimitry Andric bool Process::AreCoreFilesPrevented() { return coreFilesPrevented; }
940b57cec5SDimitry Andric 
Exit(int RetCode,bool NoCleanup)95349cc55cSDimitry Andric [[noreturn]] void Process::Exit(int RetCode, bool NoCleanup) {
9613138422SDimitry Andric   if (CrashRecoveryContext *CRC = CrashRecoveryContext::GetCurrent())
9713138422SDimitry Andric     CRC->HandleExit(RetCode);
98e8d8bef9SDimitry Andric 
99e8d8bef9SDimitry Andric   if (NoCleanup)
100fe6060f1SDimitry Andric     ExitNoCleanup(RetCode);
101e8d8bef9SDimitry Andric   else
10213138422SDimitry Andric     ::exit(RetCode);
10313138422SDimitry Andric }
10413138422SDimitry Andric 
1050b57cec5SDimitry Andric // Include the platform-specific parts of this class.
1060b57cec5SDimitry Andric #ifdef LLVM_ON_UNIX
1070b57cec5SDimitry Andric #include "Unix/Process.inc"
1080b57cec5SDimitry Andric #endif
1090b57cec5SDimitry Andric #ifdef _WIN32
1100b57cec5SDimitry Andric #include "Windows/Process.inc"
1110b57cec5SDimitry Andric #endif
112