10b57cec5SDimitry Andric //===- llvm/Support/Process.h -----------------------------------*- 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 /// \file
90b57cec5SDimitry Andric ///
100b57cec5SDimitry Andric /// Provides a library for accessing information about this process and other
110b57cec5SDimitry Andric /// processes on the operating system. Also provides means of spawning
120b57cec5SDimitry Andric /// subprocess for commands. The design of this library is modeled after the
130b57cec5SDimitry Andric /// proposed design of the Boost.Process library, and is design specifically to
140b57cec5SDimitry Andric /// follow the style of standard libraries and potentially become a proposal
150b57cec5SDimitry Andric /// for a standard library.
160b57cec5SDimitry Andric ///
170b57cec5SDimitry Andric /// This file declares the llvm::sys::Process class which contains a collection
180b57cec5SDimitry Andric /// of legacy static interfaces for extracting various information about the
190b57cec5SDimitry Andric /// current process. The goal is to migrate users of this API over to the new
200b57cec5SDimitry Andric /// interfaces.
210b57cec5SDimitry Andric ///
220b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric #ifndef LLVM_SUPPORT_PROCESS_H
250b57cec5SDimitry Andric #define LLVM_SUPPORT_PROCESS_H
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric #include "llvm/Support/Chrono.h"
280b57cec5SDimitry Andric #include "llvm/Support/DataTypes.h"
290b57cec5SDimitry Andric #include "llvm/Support/Error.h"
30e8d8bef9SDimitry Andric #include "llvm/Support/Program.h"
31bdd1243dSDimitry Andric #include <optional>
320b57cec5SDimitry Andric #include <system_error>
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric namespace llvm {
350b57cec5SDimitry Andric template <typename T> class ArrayRef;
360b57cec5SDimitry Andric class StringRef;
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric namespace sys {
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric /// A collection of legacy interfaces for querying information about the
420b57cec5SDimitry Andric /// current executing process.
430b57cec5SDimitry Andric class Process {
440b57cec5SDimitry Andric public:
455ffd83dbSDimitry Andric   using Pid = int32_t;
465ffd83dbSDimitry Andric 
475ffd83dbSDimitry Andric   /// Get the process's identifier.
485ffd83dbSDimitry Andric   static Pid getProcessId();
495ffd83dbSDimitry Andric 
500b57cec5SDimitry Andric   /// Get the process's page size.
510b57cec5SDimitry Andric   /// This may fail if the underlying syscall returns an error. In most cases,
520b57cec5SDimitry Andric   /// page size information is used for optimization, and this error can be
530b57cec5SDimitry Andric   /// safely discarded by calling consumeError, and an estimated page size
540b57cec5SDimitry Andric   /// substituted instead.
550b57cec5SDimitry Andric   static Expected<unsigned> getPageSize();
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric   /// Get the process's estimated page size.
580b57cec5SDimitry Andric   /// This function always succeeds, but if the underlying syscall to determine
590b57cec5SDimitry Andric   /// the page size fails then this will silently return an estimated page size.
600b57cec5SDimitry Andric   /// The estimated page size is guaranteed to be a power of 2.
getPageSizeEstimate()610b57cec5SDimitry Andric   static unsigned getPageSizeEstimate() {
620b57cec5SDimitry Andric     if (auto PageSize = getPageSize())
630b57cec5SDimitry Andric       return *PageSize;
640b57cec5SDimitry Andric     else {
650b57cec5SDimitry Andric       consumeError(PageSize.takeError());
660b57cec5SDimitry Andric       return 4096;
670b57cec5SDimitry Andric     }
680b57cec5SDimitry Andric   }
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric   /// Return process memory usage.
710b57cec5SDimitry Andric   /// This static function will return the total amount of memory allocated
720b57cec5SDimitry Andric   /// by the process. This only counts the memory allocated via the malloc,
730b57cec5SDimitry Andric   /// calloc and realloc functions and includes any "free" holes in the
740b57cec5SDimitry Andric   /// allocated space.
750b57cec5SDimitry Andric   static size_t GetMallocUsage();
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric   /// This static function will set \p user_time to the amount of CPU time
780b57cec5SDimitry Andric   /// spent in user (non-kernel) mode and \p sys_time to the amount of CPU
790b57cec5SDimitry Andric   /// time spent in system (kernel) mode.  If the operating system does not
800b57cec5SDimitry Andric   /// support collection of these metrics, a zero duration will be for both
810b57cec5SDimitry Andric   /// values.
820b57cec5SDimitry Andric   /// \param elapsed Returns the system_clock::now() giving current time
830b57cec5SDimitry Andric   /// \param user_time Returns the current amount of user time for the process
840b57cec5SDimitry Andric   /// \param sys_time Returns the current amount of system time for the process
850b57cec5SDimitry Andric   static void GetTimeUsage(TimePoint<> &elapsed,
860b57cec5SDimitry Andric                            std::chrono::nanoseconds &user_time,
870b57cec5SDimitry Andric                            std::chrono::nanoseconds &sys_time);
880b57cec5SDimitry Andric 
890b57cec5SDimitry Andric   /// This function makes the necessary calls to the operating system to
900b57cec5SDimitry Andric   /// prevent core files or any other kind of large memory dumps that can
910b57cec5SDimitry Andric   /// occur when a program fails.
920b57cec5SDimitry Andric   /// Prevent core file generation.
930b57cec5SDimitry Andric   static void PreventCoreFiles();
940b57cec5SDimitry Andric 
950b57cec5SDimitry Andric   /// true if PreventCoreFiles has been called, false otherwise.
960b57cec5SDimitry Andric   static bool AreCoreFilesPrevented();
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric   // This function returns the environment variable \arg name's value as a UTF-8
990b57cec5SDimitry Andric   // string. \arg Name is assumed to be in UTF-8 encoding too.
100bdd1243dSDimitry Andric   static std::optional<std::string> GetEnv(StringRef name);
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric   /// This function searches for an existing file in the list of directories
1030b57cec5SDimitry Andric   /// in a PATH like environment variable, and returns the first file found,
1040b57cec5SDimitry Andric   /// according to the order of the entries in the PATH like environment
1050b57cec5SDimitry Andric   /// variable.  If an ignore list is specified, then any folder which is in
1060b57cec5SDimitry Andric   /// the PATH like environment variable but is also in IgnoreList is not
1070b57cec5SDimitry Andric   /// considered.
108bdd1243dSDimitry Andric   static std::optional<std::string>
109bdd1243dSDimitry Andric   FindInEnvPath(StringRef EnvName, StringRef FileName,
110e8d8bef9SDimitry Andric                 ArrayRef<std::string> IgnoreList,
111e8d8bef9SDimitry Andric                 char Separator = EnvPathSeparator);
1120b57cec5SDimitry Andric 
113bdd1243dSDimitry Andric   static std::optional<std::string>
114bdd1243dSDimitry Andric   FindInEnvPath(StringRef EnvName, StringRef FileName,
115e8d8bef9SDimitry Andric                 char Separator = EnvPathSeparator);
1160b57cec5SDimitry Andric 
1170b57cec5SDimitry Andric   // This functions ensures that the standard file descriptors (input, output,
1180b57cec5SDimitry Andric   // and error) are properly mapped to a file descriptor before we use any of
1190b57cec5SDimitry Andric   // them.  This should only be called by standalone programs, library
1200b57cec5SDimitry Andric   // components should not call this.
1210b57cec5SDimitry Andric   static std::error_code FixupStandardFileDescriptors();
1220b57cec5SDimitry Andric 
1230b57cec5SDimitry Andric   // This function safely closes a file descriptor.  It is not safe to retry
1240b57cec5SDimitry Andric   // close(2) when it returns with errno equivalent to EINTR; this is because
1250b57cec5SDimitry Andric   // *nixen cannot agree if the file descriptor is, in fact, closed when this
1260b57cec5SDimitry Andric   // occurs.
1270b57cec5SDimitry Andric   //
1280b57cec5SDimitry Andric   // N.B. Some operating systems, due to thread cancellation, cannot properly
1290b57cec5SDimitry Andric   // guarantee that it will or will not be closed one way or the other!
1300b57cec5SDimitry Andric   static std::error_code SafelyCloseFileDescriptor(int FD);
1310b57cec5SDimitry Andric 
1320b57cec5SDimitry Andric   /// This function determines if the standard input is connected directly
1330b57cec5SDimitry Andric   /// to a user's input (keyboard probably), rather than coming from a file
1340b57cec5SDimitry Andric   /// or pipe.
1350b57cec5SDimitry Andric   static bool StandardInIsUserInput();
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric   /// This function determines if the standard output is connected to a
1380b57cec5SDimitry Andric   /// "tty" or "console" window. That is, the output would be displayed to
1390b57cec5SDimitry Andric   /// the user rather than being put on a pipe or stored in a file.
1400b57cec5SDimitry Andric   static bool StandardOutIsDisplayed();
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric   /// This function determines if the standard error is connected to a
1430b57cec5SDimitry Andric   /// "tty" or "console" window. That is, the output would be displayed to
1440b57cec5SDimitry Andric   /// the user rather than being put on a pipe or stored in a file.
1450b57cec5SDimitry Andric   static bool StandardErrIsDisplayed();
1460b57cec5SDimitry Andric 
1470b57cec5SDimitry Andric   /// This function determines if the given file descriptor is connected to
1480b57cec5SDimitry Andric   /// a "tty" or "console" window. That is, the output would be displayed to
1490b57cec5SDimitry Andric   /// the user rather than being put on a pipe or stored in a file.
1500b57cec5SDimitry Andric   static bool FileDescriptorIsDisplayed(int fd);
1510b57cec5SDimitry Andric 
1520b57cec5SDimitry Andric   /// This function determines if the given file descriptor is displayd and
1530b57cec5SDimitry Andric   /// supports colors.
1540b57cec5SDimitry Andric   static bool FileDescriptorHasColors(int fd);
1550b57cec5SDimitry Andric 
1560b57cec5SDimitry Andric   /// This function determines the number of columns in the window
1570b57cec5SDimitry Andric   /// if standard output is connected to a "tty" or "console"
1580b57cec5SDimitry Andric   /// window. If standard output is not connected to a tty or
1590b57cec5SDimitry Andric   /// console, or if the number of columns cannot be determined,
1600b57cec5SDimitry Andric   /// this routine returns zero.
1610b57cec5SDimitry Andric   static unsigned StandardOutColumns();
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric   /// This function determines the number of columns in the window
1640b57cec5SDimitry Andric   /// if standard error is connected to a "tty" or "console"
1650b57cec5SDimitry Andric   /// window. If standard error is not connected to a tty or
1660b57cec5SDimitry Andric   /// console, or if the number of columns cannot be determined,
1670b57cec5SDimitry Andric   /// this routine returns zero.
1680b57cec5SDimitry Andric   static unsigned StandardErrColumns();
1690b57cec5SDimitry Andric 
1700b57cec5SDimitry Andric   /// This function determines whether the terminal connected to standard
1710b57cec5SDimitry Andric   /// output supports colors. If standard output is not connected to a
1720b57cec5SDimitry Andric   /// terminal, this function returns false.
1730b57cec5SDimitry Andric   static bool StandardOutHasColors();
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric   /// This function determines whether the terminal connected to standard
1760b57cec5SDimitry Andric   /// error supports colors. If standard error is not connected to a
1770b57cec5SDimitry Andric   /// terminal, this function returns false.
1780b57cec5SDimitry Andric   static bool StandardErrHasColors();
1790b57cec5SDimitry Andric 
1800b57cec5SDimitry Andric   /// Enables or disables whether ANSI escape sequences are used to output
1810b57cec5SDimitry Andric   /// colors. This only has an effect on Windows.
1820b57cec5SDimitry Andric   /// Note: Setting this option is not thread-safe and should only be done
1830b57cec5SDimitry Andric   /// during initialization.
1840b57cec5SDimitry Andric   static void UseANSIEscapeCodes(bool enable);
1850b57cec5SDimitry Andric 
1860b57cec5SDimitry Andric   /// Whether changing colors requires the output to be flushed.
1870b57cec5SDimitry Andric   /// This is needed on systems that don't support escape sequences for
1880b57cec5SDimitry Andric   /// changing colors.
1890b57cec5SDimitry Andric   static bool ColorNeedsFlush();
1900b57cec5SDimitry Andric 
1910b57cec5SDimitry Andric   /// This function returns the colorcode escape sequences.
1920b57cec5SDimitry Andric   /// If ColorNeedsFlush() is true then this function will change the colors
1930b57cec5SDimitry Andric   /// and return an empty escape sequence. In that case it is the
1940b57cec5SDimitry Andric   /// responsibility of the client to flush the output stream prior to
1950b57cec5SDimitry Andric   /// calling this function.
1960b57cec5SDimitry Andric   static const char *OutputColor(char c, bool bold, bool bg);
1970b57cec5SDimitry Andric 
1980b57cec5SDimitry Andric   /// Same as OutputColor, but only enables the bold attribute.
1990b57cec5SDimitry Andric   static const char *OutputBold(bool bg);
2000b57cec5SDimitry Andric 
2010b57cec5SDimitry Andric   /// This function returns the escape sequence to reverse forground and
2020b57cec5SDimitry Andric   /// background colors.
2030b57cec5SDimitry Andric   static const char *OutputReverse();
2040b57cec5SDimitry Andric 
2050b57cec5SDimitry Andric   /// Resets the terminals colors, or returns an escape sequence to do so.
2060b57cec5SDimitry Andric   static const char *ResetColor();
2070b57cec5SDimitry Andric 
2080b57cec5SDimitry Andric   /// Get the result of a process wide random number generator. The
2090b57cec5SDimitry Andric   /// generator will be automatically seeded in non-deterministic fashion.
2100b57cec5SDimitry Andric   static unsigned GetRandomNumber();
21113138422SDimitry Andric 
21213138422SDimitry Andric   /// Equivalent to ::exit(), except when running inside a CrashRecoveryContext.
21313138422SDimitry Andric   /// In that case, the control flow will resume after RunSafely(), like for a
21413138422SDimitry Andric   /// crash, rather than exiting the current process.
215e8d8bef9SDimitry Andric   /// Use \arg NoCleanup for calling _exit() instead of exit().
216349cc55cSDimitry Andric   [[noreturn]] static void Exit(int RetCode, bool NoCleanup = false);
217fe6060f1SDimitry Andric 
218fe6060f1SDimitry Andric private:
219349cc55cSDimitry Andric   [[noreturn]] static void ExitNoCleanup(int RetCode);
2200b57cec5SDimitry Andric };
2210b57cec5SDimitry Andric 
2220b57cec5SDimitry Andric }
2230b57cec5SDimitry Andric }
2240b57cec5SDimitry Andric 
2250b57cec5SDimitry Andric #endif
226