1cf099d11SDimitry Andric //===-- Process.cpp - Implement OS Process Concept --------------*- C++ -*-===//
2cf099d11SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6cf099d11SDimitry Andric //
7cf099d11SDimitry Andric //===----------------------------------------------------------------------===//
8cf099d11SDimitry Andric //
95ca98fd9SDimitry Andric // This file implements the operating system Process concept.
10cf099d11SDimitry Andric //
11cf099d11SDimitry Andric //===----------------------------------------------------------------------===//
12cf099d11SDimitry Andric
137ab83427SDimitry Andric #include "llvm/Support/Process.h"
14044eb2f6SDimitry Andric #include "llvm/ADT/STLExtras.h"
155ca98fd9SDimitry Andric #include "llvm/ADT/StringExtras.h"
16d8e91e46SDimitry Andric #include "llvm/Config/config.h"
17cfca06d7SDimitry Andric #include "llvm/Config/llvm-config.h"
18cfca06d7SDimitry Andric #include "llvm/Support/CrashRecoveryContext.h"
195ca98fd9SDimitry Andric #include "llvm/Support/FileSystem.h"
205a5ac124SDimitry Andric #include "llvm/Support/Path.h"
215ca98fd9SDimitry Andric #include "llvm/Support/Program.h"
22cf099d11SDimitry Andric
23e3b55780SDimitry Andric #include <optional>
24b60736ecSDimitry Andric #include <stdlib.h> // for _Exit
25b60736ecSDimitry Andric
264a16efa3SDimitry Andric using namespace llvm;
27cf099d11SDimitry Andric using namespace sys;
28cf099d11SDimitry Andric
29cf099d11SDimitry Andric //===----------------------------------------------------------------------===//
30cf099d11SDimitry Andric //=== WARNING: Implementation here must contain only TRULY operating system
31cf099d11SDimitry Andric //=== independent code.
32cf099d11SDimitry Andric //===----------------------------------------------------------------------===//
33cf099d11SDimitry Andric
34e3b55780SDimitry Andric std::optional<std::string>
FindInEnvPath(StringRef EnvName,StringRef FileName,char Separator)35b60736ecSDimitry Andric Process::FindInEnvPath(StringRef EnvName, StringRef FileName, char Separator) {
36b60736ecSDimitry Andric return FindInEnvPath(EnvName, FileName, {}, Separator);
37044eb2f6SDimitry Andric }
38044eb2f6SDimitry Andric
39e3b55780SDimitry Andric std::optional<std::string>
FindInEnvPath(StringRef EnvName,StringRef FileName,ArrayRef<std::string> IgnoreList,char Separator)40e3b55780SDimitry Andric Process::FindInEnvPath(StringRef EnvName, StringRef FileName,
41e3b55780SDimitry Andric ArrayRef<std::string> IgnoreList, char Separator) {
425a5ac124SDimitry Andric assert(!path::is_absolute(FileName));
43e3b55780SDimitry Andric std::optional<std::string> FoundPath;
44e3b55780SDimitry Andric std::optional<std::string> OptPath = Process::GetEnv(EnvName);
45145449b1SDimitry Andric if (!OptPath)
465ca98fd9SDimitry Andric return FoundPath;
474a16efa3SDimitry Andric
48b60736ecSDimitry Andric const char EnvPathSeparatorStr[] = {Separator, '\0'};
495ca98fd9SDimitry Andric SmallVector<StringRef, 8> Dirs;
50e3b55780SDimitry Andric SplitString(*OptPath, Dirs, EnvPathSeparatorStr);
515ca98fd9SDimitry Andric
52044eb2f6SDimitry Andric for (StringRef Dir : Dirs) {
535ca98fd9SDimitry Andric if (Dir.empty())
545ca98fd9SDimitry Andric continue;
555ca98fd9SDimitry Andric
56044eb2f6SDimitry Andric if (any_of(IgnoreList, [&](StringRef S) { return fs::equivalent(S, Dir); }))
57044eb2f6SDimitry Andric continue;
58044eb2f6SDimitry Andric
595ca98fd9SDimitry Andric SmallString<128> FilePath(Dir);
605ca98fd9SDimitry Andric path::append(FilePath, FileName);
615ca98fd9SDimitry Andric if (fs::exists(Twine(FilePath))) {
624df029ccSDimitry Andric FoundPath = std::string(FilePath);
635ca98fd9SDimitry Andric break;
645ca98fd9SDimitry Andric }
655ca98fd9SDimitry Andric }
665ca98fd9SDimitry Andric
675ca98fd9SDimitry Andric return FoundPath;
685ca98fd9SDimitry Andric }
694a16efa3SDimitry Andric
70ac9a064cSDimitry Andric // clang-format off
71f8af5cf6SDimitry Andric #define COLOR(FGBG, CODE, BOLD) "\033[0;" BOLD FGBG CODE "m"
72f8af5cf6SDimitry Andric
73ac9a064cSDimitry Andric #define ALLCOLORS(FGBG, BRIGHT, BOLD) \
74ac9a064cSDimitry Andric { \
75f8af5cf6SDimitry Andric COLOR(FGBG, "0", BOLD), \
76f8af5cf6SDimitry Andric COLOR(FGBG, "1", BOLD), \
77f8af5cf6SDimitry Andric COLOR(FGBG, "2", BOLD), \
78f8af5cf6SDimitry Andric COLOR(FGBG, "3", BOLD), \
79f8af5cf6SDimitry Andric COLOR(FGBG, "4", BOLD), \
80f8af5cf6SDimitry Andric COLOR(FGBG, "5", BOLD), \
81f8af5cf6SDimitry Andric COLOR(FGBG, "6", BOLD), \
82ac9a064cSDimitry Andric COLOR(FGBG, "7", BOLD), \
83ac9a064cSDimitry Andric COLOR(BRIGHT, "0", BOLD), \
84ac9a064cSDimitry Andric COLOR(BRIGHT, "1", BOLD), \
85ac9a064cSDimitry Andric COLOR(BRIGHT, "2", BOLD), \
86ac9a064cSDimitry Andric COLOR(BRIGHT, "3", BOLD), \
87ac9a064cSDimitry Andric COLOR(BRIGHT, "4", BOLD), \
88ac9a064cSDimitry Andric COLOR(BRIGHT, "5", BOLD), \
89ac9a064cSDimitry Andric COLOR(BRIGHT, "6", BOLD), \
90ac9a064cSDimitry Andric COLOR(BRIGHT, "7", BOLD), \
91f8af5cf6SDimitry Andric }
92f8af5cf6SDimitry Andric
93ac9a064cSDimitry Andric // bg
94ac9a064cSDimitry Andric // | bold
95ac9a064cSDimitry Andric // | |
96ac9a064cSDimitry Andric // | | codes
97ac9a064cSDimitry Andric // | | |
98ac9a064cSDimitry Andric // | | |
99ac9a064cSDimitry Andric static const char colorcodes[2][2][16][11] = {
100ac9a064cSDimitry Andric { ALLCOLORS("3", "9", ""), ALLCOLORS("3", "9", "1;"),},
101ac9a064cSDimitry Andric { ALLCOLORS("4", "10", ""), ALLCOLORS("4", "10", "1;")}
102f8af5cf6SDimitry Andric };
103ac9a064cSDimitry Andric // clang-format on
104f8af5cf6SDimitry Andric
105d8e91e46SDimitry Andric // A CMake option controls wheter we emit core dumps by default. An application
106d8e91e46SDimitry Andric // may disable core dumps by calling Process::PreventCoreFiles().
107d8e91e46SDimitry Andric static bool coreFilesPrevented = !LLVM_ENABLE_CRASH_DUMPS;
10801095a5dSDimitry Andric
AreCoreFilesPrevented()109d8e91e46SDimitry Andric bool Process::AreCoreFilesPrevented() { return coreFilesPrevented; }
11001095a5dSDimitry Andric
Exit(int RetCode,bool NoCleanup)111c0981da4SDimitry Andric [[noreturn]] void Process::Exit(int RetCode, bool NoCleanup) {
112cfca06d7SDimitry Andric if (CrashRecoveryContext *CRC = CrashRecoveryContext::GetCurrent())
113cfca06d7SDimitry Andric CRC->HandleExit(RetCode);
114b60736ecSDimitry Andric
115b60736ecSDimitry Andric if (NoCleanup)
116344a3780SDimitry Andric ExitNoCleanup(RetCode);
117b60736ecSDimitry Andric else
118cfca06d7SDimitry Andric ::exit(RetCode);
119cfca06d7SDimitry Andric }
120cfca06d7SDimitry Andric
121cf099d11SDimitry Andric // Include the platform-specific parts of this class.
122cf099d11SDimitry Andric #ifdef LLVM_ON_UNIX
123cf099d11SDimitry Andric #include "Unix/Process.inc"
124cf099d11SDimitry Andric #endif
125eb11fae6SDimitry Andric #ifdef _WIN32
126cf099d11SDimitry Andric #include "Windows/Process.inc"
127cf099d11SDimitry Andric #endif
128