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