1 | //===- llvm/Support/Process.h -----------------------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | /// \file |
9 | /// |
10 | /// Provides a library for accessing information about this process and other |
11 | /// processes on the operating system. Also provides means of spawning |
12 | /// subprocess for commands. The design of this library is modeled after the |
13 | /// proposed design of the Boost.Process library, and is design specifically to |
14 | /// follow the style of standard libraries and potentially become a proposal |
15 | /// for a standard library. |
16 | /// |
17 | /// This file declares the llvm::sys::Process class which contains a collection |
18 | /// of legacy static interfaces for extracting various information about the |
19 | /// current process. The goal is to migrate users of this API over to the new |
20 | /// interfaces. |
21 | /// |
22 | //===----------------------------------------------------------------------===// |
23 | |
24 | #ifndef LLVM_SUPPORT_PROCESS_H |
25 | #define LLVM_SUPPORT_PROCESS_H |
26 | |
27 | #include "llvm/Support/Chrono.h" |
28 | #include "llvm/Support/DataTypes.h" |
29 | #include "llvm/Support/Error.h" |
30 | #include "llvm/Support/Program.h" |
31 | #include <optional> |
32 | #include <system_error> |
33 | |
34 | namespace llvm { |
35 | template <typename T> class ArrayRef; |
36 | class StringRef; |
37 | |
38 | namespace sys { |
39 | |
40 | |
41 | /// A collection of legacy interfaces for querying information about the |
42 | /// current executing process. |
43 | class Process { |
44 | public: |
45 | using Pid = int32_t; |
46 | |
47 | /// Get the process's identifier. |
48 | static Pid getProcessId(); |
49 | |
50 | /// Get the process's page size. |
51 | /// This may fail if the underlying syscall returns an error. In most cases, |
52 | /// page size information is used for optimization, and this error can be |
53 | /// safely discarded by calling consumeError, and an estimated page size |
54 | /// substituted instead. |
55 | static Expected<unsigned> getPageSize(); |
56 | |
57 | /// Get the process's estimated page size. |
58 | /// This function always succeeds, but if the underlying syscall to determine |
59 | /// the page size fails then this will silently return an estimated page size. |
60 | /// The estimated page size is guaranteed to be a power of 2. |
61 | static unsigned getPageSizeEstimate() { |
62 | if (auto PageSize = getPageSize()) |
63 | return *PageSize; |
64 | else { |
65 | consumeError(Err: PageSize.takeError()); |
66 | return 4096; |
67 | } |
68 | } |
69 | |
70 | /// Return process memory usage. |
71 | /// This static function will return the total amount of memory allocated |
72 | /// by the process. This only counts the memory allocated via the malloc, |
73 | /// calloc and realloc functions and includes any "free" holes in the |
74 | /// allocated space. |
75 | static size_t GetMallocUsage(); |
76 | |
77 | /// This static function will set \p user_time to the amount of CPU time |
78 | /// spent in user (non-kernel) mode and \p sys_time to the amount of CPU |
79 | /// time spent in system (kernel) mode. If the operating system does not |
80 | /// support collection of these metrics, a zero duration will be for both |
81 | /// values. |
82 | /// \param elapsed Returns the system_clock::now() giving current time |
83 | /// \param user_time Returns the current amount of user time for the process |
84 | /// \param sys_time Returns the current amount of system time for the process |
85 | static void GetTimeUsage(TimePoint<> &elapsed, |
86 | std::chrono::nanoseconds &user_time, |
87 | std::chrono::nanoseconds &sys_time); |
88 | |
89 | /// This function makes the necessary calls to the operating system to |
90 | /// prevent core files or any other kind of large memory dumps that can |
91 | /// occur when a program fails. |
92 | /// Prevent core file generation. |
93 | static void PreventCoreFiles(); |
94 | |
95 | /// true if PreventCoreFiles has been called, false otherwise. |
96 | static bool AreCoreFilesPrevented(); |
97 | |
98 | // This function returns the environment variable \arg name's value as a UTF-8 |
99 | // string. \arg Name is assumed to be in UTF-8 encoding too. |
100 | static std::optional<std::string> GetEnv(StringRef name); |
101 | |
102 | /// This function searches for an existing file in the list of directories |
103 | /// in a PATH like environment variable, and returns the first file found, |
104 | /// according to the order of the entries in the PATH like environment |
105 | /// variable. If an ignore list is specified, then any folder which is in |
106 | /// the PATH like environment variable but is also in IgnoreList is not |
107 | /// considered. |
108 | static std::optional<std::string> |
109 | FindInEnvPath(StringRef EnvName, StringRef FileName, |
110 | ArrayRef<std::string> IgnoreList, |
111 | char Separator = EnvPathSeparator); |
112 | |
113 | static std::optional<std::string> |
114 | FindInEnvPath(StringRef EnvName, StringRef FileName, |
115 | char Separator = EnvPathSeparator); |
116 | |
117 | // This functions ensures that the standard file descriptors (input, output, |
118 | // and error) are properly mapped to a file descriptor before we use any of |
119 | // them. This should only be called by standalone programs, library |
120 | // components should not call this. |
121 | static std::error_code FixupStandardFileDescriptors(); |
122 | |
123 | // This function safely closes a file descriptor. It is not safe to retry |
124 | // close(2) when it returns with errno equivalent to EINTR; this is because |
125 | // *nixen cannot agree if the file descriptor is, in fact, closed when this |
126 | // occurs. |
127 | // |
128 | // N.B. Some operating systems, due to thread cancellation, cannot properly |
129 | // guarantee that it will or will not be closed one way or the other! |
130 | static std::error_code SafelyCloseFileDescriptor(int FD); |
131 | |
132 | /// This function determines if the standard input is connected directly |
133 | /// to a user's input (keyboard probably), rather than coming from a file |
134 | /// or pipe. |
135 | static bool StandardInIsUserInput(); |
136 | |
137 | /// This function determines if the standard output is connected to a |
138 | /// "tty" or "console" window. That is, the output would be displayed to |
139 | /// the user rather than being put on a pipe or stored in a file. |
140 | static bool StandardOutIsDisplayed(); |
141 | |
142 | /// This function determines if the standard error is connected to a |
143 | /// "tty" or "console" window. That is, the output would be displayed to |
144 | /// the user rather than being put on a pipe or stored in a file. |
145 | static bool StandardErrIsDisplayed(); |
146 | |
147 | /// This function determines if the given file descriptor is connected to |
148 | /// a "tty" or "console" window. That is, the output would be displayed to |
149 | /// the user rather than being put on a pipe or stored in a file. |
150 | static bool FileDescriptorIsDisplayed(int fd); |
151 | |
152 | /// This function determines if the given file descriptor is displayd and |
153 | /// supports colors. |
154 | static bool FileDescriptorHasColors(int fd); |
155 | |
156 | /// This function determines the number of columns in the window |
157 | /// if standard output is connected to a "tty" or "console" |
158 | /// window. If standard output is not connected to a tty or |
159 | /// console, or if the number of columns cannot be determined, |
160 | /// this routine returns zero. |
161 | static unsigned StandardOutColumns(); |
162 | |
163 | /// This function determines the number of columns in the window |
164 | /// if standard error is connected to a "tty" or "console" |
165 | /// window. If standard error is not connected to a tty or |
166 | /// console, or if the number of columns cannot be determined, |
167 | /// this routine returns zero. |
168 | static unsigned StandardErrColumns(); |
169 | |
170 | /// This function determines whether the terminal connected to standard |
171 | /// output supports colors. If standard output is not connected to a |
172 | /// terminal, this function returns false. |
173 | static bool StandardOutHasColors(); |
174 | |
175 | /// This function determines whether the terminal connected to standard |
176 | /// error supports colors. If standard error is not connected to a |
177 | /// terminal, this function returns false. |
178 | static bool StandardErrHasColors(); |
179 | |
180 | /// Enables or disables whether ANSI escape sequences are used to output |
181 | /// colors. This only has an effect on Windows. |
182 | /// Note: Setting this option is not thread-safe and should only be done |
183 | /// during initialization. |
184 | static void UseANSIEscapeCodes(bool enable); |
185 | |
186 | /// Whether changing colors requires the output to be flushed. |
187 | /// This is needed on systems that don't support escape sequences for |
188 | /// changing colors. |
189 | static bool ColorNeedsFlush(); |
190 | |
191 | /// This function returns the colorcode escape sequences. |
192 | /// If ColorNeedsFlush() is true then this function will change the colors |
193 | /// and return an empty escape sequence. In that case it is the |
194 | /// responsibility of the client to flush the output stream prior to |
195 | /// calling this function. |
196 | static const char *OutputColor(char c, bool bold, bool bg); |
197 | |
198 | /// Same as OutputColor, but only enables the bold attribute. |
199 | static const char *OutputBold(bool bg); |
200 | |
201 | /// This function returns the escape sequence to reverse forground and |
202 | /// background colors. |
203 | static const char *OutputReverse(); |
204 | |
205 | /// Resets the terminals colors, or returns an escape sequence to do so. |
206 | static const char *ResetColor(); |
207 | |
208 | /// Get the result of a process wide random number generator. The |
209 | /// generator will be automatically seeded in non-deterministic fashion. |
210 | static unsigned GetRandomNumber(); |
211 | |
212 | /// Equivalent to ::exit(), except when running inside a CrashRecoveryContext. |
213 | /// In that case, the control flow will resume after RunSafely(), like for a |
214 | /// crash, rather than exiting the current process. |
215 | /// Use \arg NoCleanup for calling _exit() instead of exit(). |
216 | [[noreturn]] static void Exit(int RetCode, bool NoCleanup = false); |
217 | |
218 | private: |
219 | [[noreturn]] static void ExitNoCleanup(int RetCode); |
220 | }; |
221 | |
222 | } |
223 | } |
224 | |
225 | #endif |
226 | |