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