xref: /aosp_15_r20/external/llvm/lib/Support/Unix/Process.inc (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker//===- Unix/Process.cpp - Unix Process Implementation --------- -*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker//
3*9880d681SAndroid Build Coastguard Worker//                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker//
5*9880d681SAndroid Build Coastguard Worker// This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker// License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker//
8*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker//
10*9880d681SAndroid Build Coastguard Worker// This file provides the generic Unix implementation of the Process class.
11*9880d681SAndroid Build Coastguard Worker//
12*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker#include "Unix.h"
15*9880d681SAndroid Build Coastguard Worker#include "llvm/ADT/Hashing.h"
16*9880d681SAndroid Build Coastguard Worker#include "llvm/ADT/StringRef.h"
17*9880d681SAndroid Build Coastguard Worker#include "llvm/Support/ManagedStatic.h"
18*9880d681SAndroid Build Coastguard Worker#include "llvm/Support/Mutex.h"
19*9880d681SAndroid Build Coastguard Worker#include "llvm/Support/MutexGuard.h"
20*9880d681SAndroid Build Coastguard Worker#include "llvm/Support/TimeValue.h"
21*9880d681SAndroid Build Coastguard Worker#if HAVE_FCNTL_H
22*9880d681SAndroid Build Coastguard Worker#include <fcntl.h>
23*9880d681SAndroid Build Coastguard Worker#endif
24*9880d681SAndroid Build Coastguard Worker#ifdef HAVE_SYS_TIME_H
25*9880d681SAndroid Build Coastguard Worker#include <sys/time.h>
26*9880d681SAndroid Build Coastguard Worker#endif
27*9880d681SAndroid Build Coastguard Worker#ifdef HAVE_SYS_RESOURCE_H
28*9880d681SAndroid Build Coastguard Worker#include <sys/resource.h>
29*9880d681SAndroid Build Coastguard Worker#endif
30*9880d681SAndroid Build Coastguard Worker#ifdef HAVE_SYS_STAT_H
31*9880d681SAndroid Build Coastguard Worker#include <sys/stat.h>
32*9880d681SAndroid Build Coastguard Worker#endif
33*9880d681SAndroid Build Coastguard Worker#if HAVE_SIGNAL_H
34*9880d681SAndroid Build Coastguard Worker#include <signal.h>
35*9880d681SAndroid Build Coastguard Worker#endif
36*9880d681SAndroid Build Coastguard Worker// DragonFlyBSD, OpenBSD, and Bitrig have deprecated <malloc.h> for
37*9880d681SAndroid Build Coastguard Worker// <stdlib.h> instead. Unix.h includes this for us already.
38*9880d681SAndroid Build Coastguard Worker#if defined(HAVE_MALLOC_H) && !defined(__DragonFly__) && \
39*9880d681SAndroid Build Coastguard Worker    !defined(__OpenBSD__) && !defined(__Bitrig__)
40*9880d681SAndroid Build Coastguard Worker#include <malloc.h>
41*9880d681SAndroid Build Coastguard Worker#endif
42*9880d681SAndroid Build Coastguard Worker#if defined(HAVE_MALLCTL)
43*9880d681SAndroid Build Coastguard Worker#include <malloc_np.h>
44*9880d681SAndroid Build Coastguard Worker#endif
45*9880d681SAndroid Build Coastguard Worker#ifdef HAVE_MALLOC_MALLOC_H
46*9880d681SAndroid Build Coastguard Worker#include <malloc/malloc.h>
47*9880d681SAndroid Build Coastguard Worker#endif
48*9880d681SAndroid Build Coastguard Worker#ifdef HAVE_SYS_IOCTL_H
49*9880d681SAndroid Build Coastguard Worker#  include <sys/ioctl.h>
50*9880d681SAndroid Build Coastguard Worker#endif
51*9880d681SAndroid Build Coastguard Worker#ifdef HAVE_TERMIOS_H
52*9880d681SAndroid Build Coastguard Worker#  include <termios.h>
53*9880d681SAndroid Build Coastguard Worker#endif
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
56*9880d681SAndroid Build Coastguard Worker//=== WARNING: Implementation here must contain only generic UNIX code that
57*9880d681SAndroid Build Coastguard Worker//===          is guaranteed to work on *all* UNIX variants.
58*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
59*9880d681SAndroid Build Coastguard Worker
60*9880d681SAndroid Build Coastguard Workerusing namespace llvm;
61*9880d681SAndroid Build Coastguard Workerusing namespace sys;
62*9880d681SAndroid Build Coastguard Worker
63*9880d681SAndroid Build Coastguard Workerstatic std::pair<TimeValue, TimeValue> getRUsageTimes() {
64*9880d681SAndroid Build Coastguard Worker#if defined(HAVE_GETRUSAGE)
65*9880d681SAndroid Build Coastguard Worker  struct rusage RU;
66*9880d681SAndroid Build Coastguard Worker  ::getrusage(RUSAGE_SELF, &RU);
67*9880d681SAndroid Build Coastguard Worker  return std::make_pair(
68*9880d681SAndroid Build Coastguard Worker      TimeValue(
69*9880d681SAndroid Build Coastguard Worker          static_cast<TimeValue::SecondsType>(RU.ru_utime.tv_sec),
70*9880d681SAndroid Build Coastguard Worker          static_cast<TimeValue::NanoSecondsType>(
71*9880d681SAndroid Build Coastguard Worker              RU.ru_utime.tv_usec * TimeValue::NANOSECONDS_PER_MICROSECOND)),
72*9880d681SAndroid Build Coastguard Worker      TimeValue(
73*9880d681SAndroid Build Coastguard Worker          static_cast<TimeValue::SecondsType>(RU.ru_stime.tv_sec),
74*9880d681SAndroid Build Coastguard Worker          static_cast<TimeValue::NanoSecondsType>(
75*9880d681SAndroid Build Coastguard Worker              RU.ru_stime.tv_usec * TimeValue::NANOSECONDS_PER_MICROSECOND)));
76*9880d681SAndroid Build Coastguard Worker#else
77*9880d681SAndroid Build Coastguard Worker#warning Cannot get usage times on this platform
78*9880d681SAndroid Build Coastguard Worker  return std::make_pair(TimeValue(), TimeValue());
79*9880d681SAndroid Build Coastguard Worker#endif
80*9880d681SAndroid Build Coastguard Worker}
81*9880d681SAndroid Build Coastguard Worker
82*9880d681SAndroid Build Coastguard Worker// On Cygwin, getpagesize() returns 64k(AllocationGranularity) and
83*9880d681SAndroid Build Coastguard Worker// offset in mmap(3) should be aligned to the AllocationGranularity.
84*9880d681SAndroid Build Coastguard Workerunsigned Process::getPageSize() {
85*9880d681SAndroid Build Coastguard Worker#if defined(HAVE_GETPAGESIZE)
86*9880d681SAndroid Build Coastguard Worker  static const int page_size = ::getpagesize();
87*9880d681SAndroid Build Coastguard Worker#elif defined(HAVE_SYSCONF)
88*9880d681SAndroid Build Coastguard Worker  static long page_size = ::sysconf(_SC_PAGE_SIZE);
89*9880d681SAndroid Build Coastguard Worker#else
90*9880d681SAndroid Build Coastguard Worker#warning Cannot get the page size on this machine
91*9880d681SAndroid Build Coastguard Worker#endif
92*9880d681SAndroid Build Coastguard Worker  return static_cast<unsigned>(page_size);
93*9880d681SAndroid Build Coastguard Worker}
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Workersize_t Process::GetMallocUsage() {
96*9880d681SAndroid Build Coastguard Worker#if defined(HAVE_MALLINFO)
97*9880d681SAndroid Build Coastguard Worker  struct mallinfo mi;
98*9880d681SAndroid Build Coastguard Worker  mi = ::mallinfo();
99*9880d681SAndroid Build Coastguard Worker  return mi.uordblks;
100*9880d681SAndroid Build Coastguard Worker#elif defined(HAVE_MALLOC_ZONE_STATISTICS) && defined(HAVE_MALLOC_MALLOC_H)
101*9880d681SAndroid Build Coastguard Worker  malloc_statistics_t Stats;
102*9880d681SAndroid Build Coastguard Worker  malloc_zone_statistics(malloc_default_zone(), &Stats);
103*9880d681SAndroid Build Coastguard Worker  return Stats.size_in_use;   // darwin
104*9880d681SAndroid Build Coastguard Worker#elif defined(HAVE_MALLCTL)
105*9880d681SAndroid Build Coastguard Worker  size_t alloc, sz;
106*9880d681SAndroid Build Coastguard Worker  sz = sizeof(size_t);
107*9880d681SAndroid Build Coastguard Worker  if (mallctl("stats.allocated", &alloc, &sz, NULL, 0) == 0)
108*9880d681SAndroid Build Coastguard Worker    return alloc;
109*9880d681SAndroid Build Coastguard Worker  return 0;
110*9880d681SAndroid Build Coastguard Worker#elif defined(HAVE_SBRK)
111*9880d681SAndroid Build Coastguard Worker  // Note this is only an approximation and more closely resembles
112*9880d681SAndroid Build Coastguard Worker  // the value returned by mallinfo in the arena field.
113*9880d681SAndroid Build Coastguard Worker  static char *StartOfMemory = reinterpret_cast<char*>(::sbrk(0));
114*9880d681SAndroid Build Coastguard Worker  char *EndOfMemory = (char*)sbrk(0);
115*9880d681SAndroid Build Coastguard Worker  if (EndOfMemory != ((char*)-1) && StartOfMemory != ((char*)-1))
116*9880d681SAndroid Build Coastguard Worker    return EndOfMemory - StartOfMemory;
117*9880d681SAndroid Build Coastguard Worker  return 0;
118*9880d681SAndroid Build Coastguard Worker#else
119*9880d681SAndroid Build Coastguard Worker#warning Cannot get malloc info on this platform
120*9880d681SAndroid Build Coastguard Worker  return 0;
121*9880d681SAndroid Build Coastguard Worker#endif
122*9880d681SAndroid Build Coastguard Worker}
123*9880d681SAndroid Build Coastguard Worker
124*9880d681SAndroid Build Coastguard Workervoid Process::GetTimeUsage(TimeValue &elapsed, TimeValue &user_time,
125*9880d681SAndroid Build Coastguard Worker                           TimeValue &sys_time) {
126*9880d681SAndroid Build Coastguard Worker  elapsed = TimeValue::now();
127*9880d681SAndroid Build Coastguard Worker  std::tie(user_time, sys_time) = getRUsageTimes();
128*9880d681SAndroid Build Coastguard Worker}
129*9880d681SAndroid Build Coastguard Worker
130*9880d681SAndroid Build Coastguard Worker#if defined(HAVE_MACH_MACH_H) && !defined(__GNU__)
131*9880d681SAndroid Build Coastguard Worker#include <mach/mach.h>
132*9880d681SAndroid Build Coastguard Worker#endif
133*9880d681SAndroid Build Coastguard Worker
134*9880d681SAndroid Build Coastguard Worker// Some LLVM programs such as bugpoint produce core files as a normal part of
135*9880d681SAndroid Build Coastguard Worker// their operation. To prevent the disk from filling up, this function
136*9880d681SAndroid Build Coastguard Worker// does what's necessary to prevent their generation.
137*9880d681SAndroid Build Coastguard Workervoid Process::PreventCoreFiles() {
138*9880d681SAndroid Build Coastguard Worker#if HAVE_SETRLIMIT
139*9880d681SAndroid Build Coastguard Worker  struct rlimit rlim;
140*9880d681SAndroid Build Coastguard Worker  rlim.rlim_cur = rlim.rlim_max = 0;
141*9880d681SAndroid Build Coastguard Worker  setrlimit(RLIMIT_CORE, &rlim);
142*9880d681SAndroid Build Coastguard Worker#endif
143*9880d681SAndroid Build Coastguard Worker
144*9880d681SAndroid Build Coastguard Worker#if defined(HAVE_MACH_MACH_H) && !defined(__GNU__)
145*9880d681SAndroid Build Coastguard Worker  // Disable crash reporting on Mac OS X 10.0-10.4
146*9880d681SAndroid Build Coastguard Worker
147*9880d681SAndroid Build Coastguard Worker  // get information about the original set of exception ports for the task
148*9880d681SAndroid Build Coastguard Worker  mach_msg_type_number_t Count = 0;
149*9880d681SAndroid Build Coastguard Worker  exception_mask_t OriginalMasks[EXC_TYPES_COUNT];
150*9880d681SAndroid Build Coastguard Worker  exception_port_t OriginalPorts[EXC_TYPES_COUNT];
151*9880d681SAndroid Build Coastguard Worker  exception_behavior_t OriginalBehaviors[EXC_TYPES_COUNT];
152*9880d681SAndroid Build Coastguard Worker  thread_state_flavor_t OriginalFlavors[EXC_TYPES_COUNT];
153*9880d681SAndroid Build Coastguard Worker  kern_return_t err =
154*9880d681SAndroid Build Coastguard Worker    task_get_exception_ports(mach_task_self(), EXC_MASK_ALL, OriginalMasks,
155*9880d681SAndroid Build Coastguard Worker                             &Count, OriginalPorts, OriginalBehaviors,
156*9880d681SAndroid Build Coastguard Worker                             OriginalFlavors);
157*9880d681SAndroid Build Coastguard Worker  if (err == KERN_SUCCESS) {
158*9880d681SAndroid Build Coastguard Worker    // replace each with MACH_PORT_NULL.
159*9880d681SAndroid Build Coastguard Worker    for (unsigned i = 0; i != Count; ++i)
160*9880d681SAndroid Build Coastguard Worker      task_set_exception_ports(mach_task_self(), OriginalMasks[i],
161*9880d681SAndroid Build Coastguard Worker                               MACH_PORT_NULL, OriginalBehaviors[i],
162*9880d681SAndroid Build Coastguard Worker                               OriginalFlavors[i]);
163*9880d681SAndroid Build Coastguard Worker  }
164*9880d681SAndroid Build Coastguard Worker
165*9880d681SAndroid Build Coastguard Worker  // Disable crash reporting on Mac OS X 10.5
166*9880d681SAndroid Build Coastguard Worker  signal(SIGABRT, _exit);
167*9880d681SAndroid Build Coastguard Worker  signal(SIGILL,  _exit);
168*9880d681SAndroid Build Coastguard Worker  signal(SIGFPE,  _exit);
169*9880d681SAndroid Build Coastguard Worker  signal(SIGSEGV, _exit);
170*9880d681SAndroid Build Coastguard Worker  signal(SIGBUS,  _exit);
171*9880d681SAndroid Build Coastguard Worker#endif
172*9880d681SAndroid Build Coastguard Worker
173*9880d681SAndroid Build Coastguard Worker  coreFilesPrevented = true;
174*9880d681SAndroid Build Coastguard Worker}
175*9880d681SAndroid Build Coastguard Worker
176*9880d681SAndroid Build Coastguard WorkerOptional<std::string> Process::GetEnv(StringRef Name) {
177*9880d681SAndroid Build Coastguard Worker  std::string NameStr = Name.str();
178*9880d681SAndroid Build Coastguard Worker  const char *Val = ::getenv(NameStr.c_str());
179*9880d681SAndroid Build Coastguard Worker  if (!Val)
180*9880d681SAndroid Build Coastguard Worker    return None;
181*9880d681SAndroid Build Coastguard Worker  return std::string(Val);
182*9880d681SAndroid Build Coastguard Worker}
183*9880d681SAndroid Build Coastguard Worker
184*9880d681SAndroid Build Coastguard Workerstd::error_code
185*9880d681SAndroid Build Coastguard WorkerProcess::GetArgumentVector(SmallVectorImpl<const char *> &ArgsOut,
186*9880d681SAndroid Build Coastguard Worker                           ArrayRef<const char *> ArgsIn,
187*9880d681SAndroid Build Coastguard Worker                           SpecificBumpPtrAllocator<char> &) {
188*9880d681SAndroid Build Coastguard Worker  ArgsOut.append(ArgsIn.begin(), ArgsIn.end());
189*9880d681SAndroid Build Coastguard Worker
190*9880d681SAndroid Build Coastguard Worker  return std::error_code();
191*9880d681SAndroid Build Coastguard Worker}
192*9880d681SAndroid Build Coastguard Worker
193*9880d681SAndroid Build Coastguard Workernamespace {
194*9880d681SAndroid Build Coastguard Workerclass FDCloser {
195*9880d681SAndroid Build Coastguard Workerpublic:
196*9880d681SAndroid Build Coastguard Worker  FDCloser(int &FD) : FD(FD), KeepOpen(false) {}
197*9880d681SAndroid Build Coastguard Worker  void keepOpen() { KeepOpen = true; }
198*9880d681SAndroid Build Coastguard Worker  ~FDCloser() {
199*9880d681SAndroid Build Coastguard Worker    if (!KeepOpen && FD >= 0)
200*9880d681SAndroid Build Coastguard Worker      ::close(FD);
201*9880d681SAndroid Build Coastguard Worker  }
202*9880d681SAndroid Build Coastguard Worker
203*9880d681SAndroid Build Coastguard Workerprivate:
204*9880d681SAndroid Build Coastguard Worker  FDCloser(const FDCloser &) = delete;
205*9880d681SAndroid Build Coastguard Worker  void operator=(const FDCloser &) = delete;
206*9880d681SAndroid Build Coastguard Worker
207*9880d681SAndroid Build Coastguard Worker  int &FD;
208*9880d681SAndroid Build Coastguard Worker  bool KeepOpen;
209*9880d681SAndroid Build Coastguard Worker};
210*9880d681SAndroid Build Coastguard Worker}
211*9880d681SAndroid Build Coastguard Worker
212*9880d681SAndroid Build Coastguard Workerstd::error_code Process::FixupStandardFileDescriptors() {
213*9880d681SAndroid Build Coastguard Worker  int NullFD = -1;
214*9880d681SAndroid Build Coastguard Worker  FDCloser FDC(NullFD);
215*9880d681SAndroid Build Coastguard Worker  const int StandardFDs[] = {STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO};
216*9880d681SAndroid Build Coastguard Worker  for (int StandardFD : StandardFDs) {
217*9880d681SAndroid Build Coastguard Worker    struct stat st;
218*9880d681SAndroid Build Coastguard Worker    errno = 0;
219*9880d681SAndroid Build Coastguard Worker    while (fstat(StandardFD, &st) < 0) {
220*9880d681SAndroid Build Coastguard Worker      assert(errno && "expected errno to be set if fstat failed!");
221*9880d681SAndroid Build Coastguard Worker      // fstat should return EBADF if the file descriptor is closed.
222*9880d681SAndroid Build Coastguard Worker      if (errno == EBADF)
223*9880d681SAndroid Build Coastguard Worker        break;
224*9880d681SAndroid Build Coastguard Worker      // retry fstat if we got EINTR, otherwise bubble up the failure.
225*9880d681SAndroid Build Coastguard Worker      if (errno != EINTR)
226*9880d681SAndroid Build Coastguard Worker        return std::error_code(errno, std::generic_category());
227*9880d681SAndroid Build Coastguard Worker    }
228*9880d681SAndroid Build Coastguard Worker    // if fstat succeeds, move on to the next FD.
229*9880d681SAndroid Build Coastguard Worker    if (!errno)
230*9880d681SAndroid Build Coastguard Worker      continue;
231*9880d681SAndroid Build Coastguard Worker    assert(errno == EBADF && "expected errno to have EBADF at this point!");
232*9880d681SAndroid Build Coastguard Worker
233*9880d681SAndroid Build Coastguard Worker    if (NullFD < 0) {
234*9880d681SAndroid Build Coastguard Worker      while ((NullFD = open("/dev/null", O_RDWR)) < 0) {
235*9880d681SAndroid Build Coastguard Worker        if (errno == EINTR)
236*9880d681SAndroid Build Coastguard Worker          continue;
237*9880d681SAndroid Build Coastguard Worker        return std::error_code(errno, std::generic_category());
238*9880d681SAndroid Build Coastguard Worker      }
239*9880d681SAndroid Build Coastguard Worker    }
240*9880d681SAndroid Build Coastguard Worker
241*9880d681SAndroid Build Coastguard Worker    if (NullFD == StandardFD)
242*9880d681SAndroid Build Coastguard Worker      FDC.keepOpen();
243*9880d681SAndroid Build Coastguard Worker    else if (dup2(NullFD, StandardFD) < 0)
244*9880d681SAndroid Build Coastguard Worker      return std::error_code(errno, std::generic_category());
245*9880d681SAndroid Build Coastguard Worker  }
246*9880d681SAndroid Build Coastguard Worker  return std::error_code();
247*9880d681SAndroid Build Coastguard Worker}
248*9880d681SAndroid Build Coastguard Worker
249*9880d681SAndroid Build Coastguard Workerstd::error_code Process::SafelyCloseFileDescriptor(int FD) {
250*9880d681SAndroid Build Coastguard Worker  // Create a signal set filled with *all* signals.
251*9880d681SAndroid Build Coastguard Worker  sigset_t FullSet;
252*9880d681SAndroid Build Coastguard Worker  if (sigfillset(&FullSet) < 0)
253*9880d681SAndroid Build Coastguard Worker    return std::error_code(errno, std::generic_category());
254*9880d681SAndroid Build Coastguard Worker  // Atomically swap our current signal mask with a full mask.
255*9880d681SAndroid Build Coastguard Worker  sigset_t SavedSet;
256*9880d681SAndroid Build Coastguard Worker#if LLVM_ENABLE_THREADS
257*9880d681SAndroid Build Coastguard Worker  if (int EC = pthread_sigmask(SIG_SETMASK, &FullSet, &SavedSet))
258*9880d681SAndroid Build Coastguard Worker    return std::error_code(EC, std::generic_category());
259*9880d681SAndroid Build Coastguard Worker#else
260*9880d681SAndroid Build Coastguard Worker  if (sigprocmask(SIG_SETMASK, &FullSet, &SavedSet) < 0)
261*9880d681SAndroid Build Coastguard Worker    return std::error_code(errno, std::generic_category());
262*9880d681SAndroid Build Coastguard Worker#endif
263*9880d681SAndroid Build Coastguard Worker  // Attempt to close the file descriptor.
264*9880d681SAndroid Build Coastguard Worker  // We need to save the error, if one occurs, because our subsequent call to
265*9880d681SAndroid Build Coastguard Worker  // pthread_sigmask might tamper with errno.
266*9880d681SAndroid Build Coastguard Worker  int ErrnoFromClose = 0;
267*9880d681SAndroid Build Coastguard Worker  if (::close(FD) < 0)
268*9880d681SAndroid Build Coastguard Worker    ErrnoFromClose = errno;
269*9880d681SAndroid Build Coastguard Worker  // Restore the signal mask back to what we saved earlier.
270*9880d681SAndroid Build Coastguard Worker  int EC = 0;
271*9880d681SAndroid Build Coastguard Worker#if LLVM_ENABLE_THREADS
272*9880d681SAndroid Build Coastguard Worker  EC = pthread_sigmask(SIG_SETMASK, &SavedSet, nullptr);
273*9880d681SAndroid Build Coastguard Worker#else
274*9880d681SAndroid Build Coastguard Worker  if (sigprocmask(SIG_SETMASK, &SavedSet, nullptr) < 0)
275*9880d681SAndroid Build Coastguard Worker    EC = errno;
276*9880d681SAndroid Build Coastguard Worker#endif
277*9880d681SAndroid Build Coastguard Worker  // The error code from close takes precedence over the one from
278*9880d681SAndroid Build Coastguard Worker  // pthread_sigmask.
279*9880d681SAndroid Build Coastguard Worker  if (ErrnoFromClose)
280*9880d681SAndroid Build Coastguard Worker    return std::error_code(ErrnoFromClose, std::generic_category());
281*9880d681SAndroid Build Coastguard Worker  return std::error_code(EC, std::generic_category());
282*9880d681SAndroid Build Coastguard Worker}
283*9880d681SAndroid Build Coastguard Worker
284*9880d681SAndroid Build Coastguard Workerbool Process::StandardInIsUserInput() {
285*9880d681SAndroid Build Coastguard Worker  return FileDescriptorIsDisplayed(STDIN_FILENO);
286*9880d681SAndroid Build Coastguard Worker}
287*9880d681SAndroid Build Coastguard Worker
288*9880d681SAndroid Build Coastguard Workerbool Process::StandardOutIsDisplayed() {
289*9880d681SAndroid Build Coastguard Worker  return FileDescriptorIsDisplayed(STDOUT_FILENO);
290*9880d681SAndroid Build Coastguard Worker}
291*9880d681SAndroid Build Coastguard Worker
292*9880d681SAndroid Build Coastguard Workerbool Process::StandardErrIsDisplayed() {
293*9880d681SAndroid Build Coastguard Worker  return FileDescriptorIsDisplayed(STDERR_FILENO);
294*9880d681SAndroid Build Coastguard Worker}
295*9880d681SAndroid Build Coastguard Worker
296*9880d681SAndroid Build Coastguard Workerbool Process::FileDescriptorIsDisplayed(int fd) {
297*9880d681SAndroid Build Coastguard Worker#if HAVE_ISATTY
298*9880d681SAndroid Build Coastguard Worker  return isatty(fd);
299*9880d681SAndroid Build Coastguard Worker#else
300*9880d681SAndroid Build Coastguard Worker  // If we don't have isatty, just return false.
301*9880d681SAndroid Build Coastguard Worker  return false;
302*9880d681SAndroid Build Coastguard Worker#endif
303*9880d681SAndroid Build Coastguard Worker}
304*9880d681SAndroid Build Coastguard Worker
305*9880d681SAndroid Build Coastguard Workerstatic unsigned getColumns(int FileID) {
306*9880d681SAndroid Build Coastguard Worker  // If COLUMNS is defined in the environment, wrap to that many columns.
307*9880d681SAndroid Build Coastguard Worker  if (const char *ColumnsStr = std::getenv("COLUMNS")) {
308*9880d681SAndroid Build Coastguard Worker    int Columns = std::atoi(ColumnsStr);
309*9880d681SAndroid Build Coastguard Worker    if (Columns > 0)
310*9880d681SAndroid Build Coastguard Worker      return Columns;
311*9880d681SAndroid Build Coastguard Worker  }
312*9880d681SAndroid Build Coastguard Worker
313*9880d681SAndroid Build Coastguard Worker  unsigned Columns = 0;
314*9880d681SAndroid Build Coastguard Worker
315*9880d681SAndroid Build Coastguard Worker#if defined(HAVE_SYS_IOCTL_H) && defined(HAVE_TERMIOS_H)
316*9880d681SAndroid Build Coastguard Worker  // Try to determine the width of the terminal.
317*9880d681SAndroid Build Coastguard Worker  struct winsize ws;
318*9880d681SAndroid Build Coastguard Worker  if (ioctl(FileID, TIOCGWINSZ, &ws) == 0)
319*9880d681SAndroid Build Coastguard Worker    Columns = ws.ws_col;
320*9880d681SAndroid Build Coastguard Worker#endif
321*9880d681SAndroid Build Coastguard Worker
322*9880d681SAndroid Build Coastguard Worker  return Columns;
323*9880d681SAndroid Build Coastguard Worker}
324*9880d681SAndroid Build Coastguard Worker
325*9880d681SAndroid Build Coastguard Workerunsigned Process::StandardOutColumns() {
326*9880d681SAndroid Build Coastguard Worker  if (!StandardOutIsDisplayed())
327*9880d681SAndroid Build Coastguard Worker    return 0;
328*9880d681SAndroid Build Coastguard Worker
329*9880d681SAndroid Build Coastguard Worker  return getColumns(1);
330*9880d681SAndroid Build Coastguard Worker}
331*9880d681SAndroid Build Coastguard Worker
332*9880d681SAndroid Build Coastguard Workerunsigned Process::StandardErrColumns() {
333*9880d681SAndroid Build Coastguard Worker  if (!StandardErrIsDisplayed())
334*9880d681SAndroid Build Coastguard Worker    return 0;
335*9880d681SAndroid Build Coastguard Worker
336*9880d681SAndroid Build Coastguard Worker  return getColumns(2);
337*9880d681SAndroid Build Coastguard Worker}
338*9880d681SAndroid Build Coastguard Worker
339*9880d681SAndroid Build Coastguard Worker#ifdef HAVE_TERMINFO
340*9880d681SAndroid Build Coastguard Worker// We manually declare these extern functions because finding the correct
341*9880d681SAndroid Build Coastguard Worker// headers from various terminfo, curses, or other sources is harder than
342*9880d681SAndroid Build Coastguard Worker// writing their specs down.
343*9880d681SAndroid Build Coastguard Workerextern "C" int setupterm(char *term, int filedes, int *errret);
344*9880d681SAndroid Build Coastguard Workerextern "C" struct term *set_curterm(struct term *termp);
345*9880d681SAndroid Build Coastguard Workerextern "C" int del_curterm(struct term *termp);
346*9880d681SAndroid Build Coastguard Workerextern "C" int tigetnum(char *capname);
347*9880d681SAndroid Build Coastguard Worker#endif
348*9880d681SAndroid Build Coastguard Worker
349*9880d681SAndroid Build Coastguard Worker#ifdef HAVE_TERMINFO
350*9880d681SAndroid Build Coastguard Workerstatic ManagedStatic<sys::Mutex> TermColorMutex;
351*9880d681SAndroid Build Coastguard Worker#endif
352*9880d681SAndroid Build Coastguard Worker
353*9880d681SAndroid Build Coastguard Workerstatic bool terminalHasColors(int fd) {
354*9880d681SAndroid Build Coastguard Worker#ifdef HAVE_TERMINFO
355*9880d681SAndroid Build Coastguard Worker  // First, acquire a global lock because these C routines are thread hostile.
356*9880d681SAndroid Build Coastguard Worker  MutexGuard G(*TermColorMutex);
357*9880d681SAndroid Build Coastguard Worker
358*9880d681SAndroid Build Coastguard Worker  int errret = 0;
359*9880d681SAndroid Build Coastguard Worker  if (setupterm((char *)nullptr, fd, &errret) != 0)
360*9880d681SAndroid Build Coastguard Worker    // Regardless of why, if we can't get terminfo, we shouldn't try to print
361*9880d681SAndroid Build Coastguard Worker    // colors.
362*9880d681SAndroid Build Coastguard Worker    return false;
363*9880d681SAndroid Build Coastguard Worker
364*9880d681SAndroid Build Coastguard Worker  // Test whether the terminal as set up supports color output. How to do this
365*9880d681SAndroid Build Coastguard Worker  // isn't entirely obvious. We can use the curses routine 'has_colors' but it
366*9880d681SAndroid Build Coastguard Worker  // would be nice to avoid a dependency on curses proper when we can make do
367*9880d681SAndroid Build Coastguard Worker  // with a minimal terminfo parsing library. Also, we don't really care whether
368*9880d681SAndroid Build Coastguard Worker  // the terminal supports the curses-specific color changing routines, merely
369*9880d681SAndroid Build Coastguard Worker  // if it will interpret ANSI color escape codes in a reasonable way. Thus, the
370*9880d681SAndroid Build Coastguard Worker  // strategy here is just to query the baseline colors capability and if it
371*9880d681SAndroid Build Coastguard Worker  // supports colors at all to assume it will translate the escape codes into
372*9880d681SAndroid Build Coastguard Worker  // whatever range of colors it does support. We can add more detailed tests
373*9880d681SAndroid Build Coastguard Worker  // here if users report them as necessary.
374*9880d681SAndroid Build Coastguard Worker  //
375*9880d681SAndroid Build Coastguard Worker  // The 'tigetnum' routine returns -2 or -1 on errors, and might return 0 if
376*9880d681SAndroid Build Coastguard Worker  // the terminfo says that no colors are supported.
377*9880d681SAndroid Build Coastguard Worker  bool HasColors = tigetnum(const_cast<char *>("colors")) > 0;
378*9880d681SAndroid Build Coastguard Worker
379*9880d681SAndroid Build Coastguard Worker  // Now extract the structure allocated by setupterm and free its memory
380*9880d681SAndroid Build Coastguard Worker  // through a really silly dance.
381*9880d681SAndroid Build Coastguard Worker  struct term *termp = set_curterm((struct term *)nullptr);
382*9880d681SAndroid Build Coastguard Worker  (void)del_curterm(termp); // Drop any errors here.
383*9880d681SAndroid Build Coastguard Worker
384*9880d681SAndroid Build Coastguard Worker  // Return true if we found a color capabilities for the current terminal.
385*9880d681SAndroid Build Coastguard Worker  if (HasColors)
386*9880d681SAndroid Build Coastguard Worker    return true;
387*9880d681SAndroid Build Coastguard Worker#endif
388*9880d681SAndroid Build Coastguard Worker
389*9880d681SAndroid Build Coastguard Worker  // Otherwise, be conservative.
390*9880d681SAndroid Build Coastguard Worker  return false;
391*9880d681SAndroid Build Coastguard Worker}
392*9880d681SAndroid Build Coastguard Worker
393*9880d681SAndroid Build Coastguard Workerbool Process::FileDescriptorHasColors(int fd) {
394*9880d681SAndroid Build Coastguard Worker  // A file descriptor has colors if it is displayed and the terminal has
395*9880d681SAndroid Build Coastguard Worker  // colors.
396*9880d681SAndroid Build Coastguard Worker  return FileDescriptorIsDisplayed(fd) && terminalHasColors(fd);
397*9880d681SAndroid Build Coastguard Worker}
398*9880d681SAndroid Build Coastguard Worker
399*9880d681SAndroid Build Coastguard Workerbool Process::StandardOutHasColors() {
400*9880d681SAndroid Build Coastguard Worker  return FileDescriptorHasColors(STDOUT_FILENO);
401*9880d681SAndroid Build Coastguard Worker}
402*9880d681SAndroid Build Coastguard Worker
403*9880d681SAndroid Build Coastguard Workerbool Process::StandardErrHasColors() {
404*9880d681SAndroid Build Coastguard Worker  return FileDescriptorHasColors(STDERR_FILENO);
405*9880d681SAndroid Build Coastguard Worker}
406*9880d681SAndroid Build Coastguard Worker
407*9880d681SAndroid Build Coastguard Workervoid Process::UseANSIEscapeCodes(bool /*enable*/) {
408*9880d681SAndroid Build Coastguard Worker  // No effect.
409*9880d681SAndroid Build Coastguard Worker}
410*9880d681SAndroid Build Coastguard Worker
411*9880d681SAndroid Build Coastguard Workerbool Process::ColorNeedsFlush() {
412*9880d681SAndroid Build Coastguard Worker  // No, we use ANSI escape sequences.
413*9880d681SAndroid Build Coastguard Worker  return false;
414*9880d681SAndroid Build Coastguard Worker}
415*9880d681SAndroid Build Coastguard Worker
416*9880d681SAndroid Build Coastguard Workerconst char *Process::OutputColor(char code, bool bold, bool bg) {
417*9880d681SAndroid Build Coastguard Worker  return colorcodes[bg?1:0][bold?1:0][code&7];
418*9880d681SAndroid Build Coastguard Worker}
419*9880d681SAndroid Build Coastguard Worker
420*9880d681SAndroid Build Coastguard Workerconst char *Process::OutputBold(bool bg) {
421*9880d681SAndroid Build Coastguard Worker  return "\033[1m";
422*9880d681SAndroid Build Coastguard Worker}
423*9880d681SAndroid Build Coastguard Worker
424*9880d681SAndroid Build Coastguard Workerconst char *Process::OutputReverse() {
425*9880d681SAndroid Build Coastguard Worker  return "\033[7m";
426*9880d681SAndroid Build Coastguard Worker}
427*9880d681SAndroid Build Coastguard Worker
428*9880d681SAndroid Build Coastguard Workerconst char *Process::ResetColor() {
429*9880d681SAndroid Build Coastguard Worker  return "\033[0m";
430*9880d681SAndroid Build Coastguard Worker}
431*9880d681SAndroid Build Coastguard Worker
432*9880d681SAndroid Build Coastguard Worker#if !defined(HAVE_DECL_ARC4RANDOM) || !HAVE_DECL_ARC4RANDOM
433*9880d681SAndroid Build Coastguard Workerstatic unsigned GetRandomNumberSeed() {
434*9880d681SAndroid Build Coastguard Worker  // Attempt to get the initial seed from /dev/urandom, if possible.
435*9880d681SAndroid Build Coastguard Worker  int urandomFD = open("/dev/urandom", O_RDONLY);
436*9880d681SAndroid Build Coastguard Worker
437*9880d681SAndroid Build Coastguard Worker  if (urandomFD != -1) {
438*9880d681SAndroid Build Coastguard Worker    unsigned seed;
439*9880d681SAndroid Build Coastguard Worker    // Don't use a buffered read to avoid reading more data
440*9880d681SAndroid Build Coastguard Worker    // from /dev/urandom than we need.
441*9880d681SAndroid Build Coastguard Worker    int count = read(urandomFD, (void *)&seed, sizeof(seed));
442*9880d681SAndroid Build Coastguard Worker
443*9880d681SAndroid Build Coastguard Worker    close(urandomFD);
444*9880d681SAndroid Build Coastguard Worker
445*9880d681SAndroid Build Coastguard Worker    // Return the seed if the read was successful.
446*9880d681SAndroid Build Coastguard Worker    if (count == sizeof(seed))
447*9880d681SAndroid Build Coastguard Worker      return seed;
448*9880d681SAndroid Build Coastguard Worker  }
449*9880d681SAndroid Build Coastguard Worker
450*9880d681SAndroid Build Coastguard Worker  // Otherwise, swizzle the current time and the process ID to form a reasonable
451*9880d681SAndroid Build Coastguard Worker  // seed.
452*9880d681SAndroid Build Coastguard Worker  TimeValue Now = TimeValue::now();
453*9880d681SAndroid Build Coastguard Worker  return hash_combine(Now.seconds(), Now.nanoseconds(), ::getpid());
454*9880d681SAndroid Build Coastguard Worker}
455*9880d681SAndroid Build Coastguard Worker#endif
456*9880d681SAndroid Build Coastguard Worker
457*9880d681SAndroid Build Coastguard Workerunsigned llvm::sys::Process::GetRandomNumber() {
458*9880d681SAndroid Build Coastguard Worker#if defined(HAVE_DECL_ARC4RANDOM) && HAVE_DECL_ARC4RANDOM
459*9880d681SAndroid Build Coastguard Worker  return arc4random();
460*9880d681SAndroid Build Coastguard Worker#else
461*9880d681SAndroid Build Coastguard Worker  static int x = (static_cast<void>(::srand(GetRandomNumberSeed())), 0);
462*9880d681SAndroid Build Coastguard Worker  (void)x;
463*9880d681SAndroid Build Coastguard Worker  return ::rand();
464*9880d681SAndroid Build Coastguard Worker#endif
465*9880d681SAndroid Build Coastguard Worker}
466