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