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