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 
23af732203SDimitry Andric #include <stdlib.h> // for _Exit
24af732203SDimitry Andric 
250b57cec5SDimitry Andric using namespace llvm;
260b57cec5SDimitry Andric using namespace sys;
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
290b57cec5SDimitry Andric //=== WARNING: Implementation here must contain only TRULY operating system
300b57cec5SDimitry Andric //===          independent code.
310b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
320b57cec5SDimitry Andric 
33af732203SDimitry Andric Optional<std::string>
FindInEnvPath(StringRef EnvName,StringRef FileName,char Separator)34af732203SDimitry Andric Process::FindInEnvPath(StringRef EnvName, StringRef FileName, char Separator) {
35af732203SDimitry Andric   return FindInEnvPath(EnvName, FileName, {}, Separator);
360b57cec5SDimitry Andric }
370b57cec5SDimitry Andric 
FindInEnvPath(StringRef EnvName,StringRef FileName,ArrayRef<std::string> IgnoreList,char Separator)380b57cec5SDimitry Andric Optional<std::string> Process::FindInEnvPath(StringRef EnvName,
390b57cec5SDimitry Andric                                              StringRef FileName,
40af732203SDimitry Andric                                              ArrayRef<std::string> IgnoreList,
41af732203SDimitry Andric                                              char Separator) {
420b57cec5SDimitry Andric   assert(!path::is_absolute(FileName));
430b57cec5SDimitry Andric   Optional<std::string> FoundPath;
440b57cec5SDimitry Andric   Optional<std::string> OptPath = Process::GetEnv(EnvName);
450b57cec5SDimitry Andric   if (!OptPath.hasValue())
460b57cec5SDimitry Andric     return FoundPath;
470b57cec5SDimitry Andric 
48af732203SDimitry Andric   const char EnvPathSeparatorStr[] = {Separator, '\0'};
490b57cec5SDimitry Andric   SmallVector<StringRef, 8> Dirs;
500b57cec5SDimitry Andric   SplitString(OptPath.getValue(), 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))) {
625ffd83dbSDimitry Andric       FoundPath = std::string(FilePath.str());
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 
9513138422SDimitry Andric LLVM_ATTRIBUTE_NORETURN
Exit(int RetCode,bool NoCleanup)96af732203SDimitry Andric void Process::Exit(int RetCode, bool NoCleanup) {
9713138422SDimitry Andric   if (CrashRecoveryContext *CRC = CrashRecoveryContext::GetCurrent())
9813138422SDimitry Andric     CRC->HandleExit(RetCode);
99af732203SDimitry Andric 
100af732203SDimitry Andric   if (NoCleanup)
101*5f7ddb14SDimitry Andric     ExitNoCleanup(RetCode);
102af732203SDimitry Andric   else
10313138422SDimitry Andric     ::exit(RetCode);
10413138422SDimitry Andric }
10513138422SDimitry Andric 
1060b57cec5SDimitry Andric // Include the platform-specific parts of this class.
1070b57cec5SDimitry Andric #ifdef LLVM_ON_UNIX
1080b57cec5SDimitry Andric #include "Unix/Process.inc"
1090b57cec5SDimitry Andric #endif
1100b57cec5SDimitry Andric #ifdef _WIN32
1110b57cec5SDimitry Andric #include "Windows/Process.inc"
1120b57cec5SDimitry Andric #endif
113