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