xref: /aosp_15_r20/external/llvm/lib/Support/Unix/Program.inc (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker//===- llvm/Support/Unix/Program.cpp -----------------------------*- 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 implements the Unix specific portion of the Program class.
11*9880d681SAndroid Build Coastguard Worker//
12*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
15*9880d681SAndroid Build Coastguard Worker//=== WARNING: Implementation here must contain only generic UNIX code that
16*9880d681SAndroid Build Coastguard Worker//===          is guaranteed to work on *all* UNIX variants.
17*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
18*9880d681SAndroid Build Coastguard Worker
19*9880d681SAndroid Build Coastguard Worker#include "Unix.h"
20*9880d681SAndroid Build Coastguard Worker#include "llvm/ADT/StringExtras.h"
21*9880d681SAndroid Build Coastguard Worker#include "llvm/Config/config.h"
22*9880d681SAndroid Build Coastguard Worker#include "llvm/Support/Compiler.h"
23*9880d681SAndroid Build Coastguard Worker#include "llvm/Support/Errc.h"
24*9880d681SAndroid Build Coastguard Worker#include "llvm/Support/FileSystem.h"
25*9880d681SAndroid Build Coastguard Worker#include "llvm/Support/Path.h"
26*9880d681SAndroid Build Coastguard Worker#include "llvm/Support/raw_ostream.h"
27*9880d681SAndroid Build Coastguard Worker#if HAVE_SYS_STAT_H
28*9880d681SAndroid Build Coastguard Worker#include <sys/stat.h>
29*9880d681SAndroid Build Coastguard Worker#endif
30*9880d681SAndroid Build Coastguard Worker#if HAVE_SYS_RESOURCE_H
31*9880d681SAndroid Build Coastguard Worker#include <sys/resource.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#if HAVE_FCNTL_H
37*9880d681SAndroid Build Coastguard Worker#include <fcntl.h>
38*9880d681SAndroid Build Coastguard Worker#endif
39*9880d681SAndroid Build Coastguard Worker#if HAVE_UNISTD_H
40*9880d681SAndroid Build Coastguard Worker#include <unistd.h>
41*9880d681SAndroid Build Coastguard Worker#endif
42*9880d681SAndroid Build Coastguard Worker#ifdef HAVE_POSIX_SPAWN
43*9880d681SAndroid Build Coastguard Worker#ifdef __sun__
44*9880d681SAndroid Build Coastguard Worker#define  _RESTRICT_KYWD
45*9880d681SAndroid Build Coastguard Worker#endif
46*9880d681SAndroid Build Coastguard Worker#include <spawn.h>
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Worker#if defined(__APPLE__)
49*9880d681SAndroid Build Coastguard Worker#include <TargetConditionals.h>
50*9880d681SAndroid Build Coastguard Worker#endif
51*9880d681SAndroid Build Coastguard Worker
52*9880d681SAndroid Build Coastguard Worker#if defined(__APPLE__) && !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)
53*9880d681SAndroid Build Coastguard Worker#define USE_NSGETENVIRON 1
54*9880d681SAndroid Build Coastguard Worker#else
55*9880d681SAndroid Build Coastguard Worker#define USE_NSGETENVIRON 0
56*9880d681SAndroid Build Coastguard Worker#endif
57*9880d681SAndroid Build Coastguard Worker
58*9880d681SAndroid Build Coastguard Worker#if !USE_NSGETENVIRON
59*9880d681SAndroid Build Coastguard Worker  extern char **environ;
60*9880d681SAndroid Build Coastguard Worker#else
61*9880d681SAndroid Build Coastguard Worker#include <crt_externs.h> // _NSGetEnviron
62*9880d681SAndroid Build Coastguard Worker#endif
63*9880d681SAndroid Build Coastguard Worker#endif
64*9880d681SAndroid Build Coastguard Worker
65*9880d681SAndroid Build Coastguard Workernamespace llvm {
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Workerusing namespace sys;
68*9880d681SAndroid Build Coastguard Worker
69*9880d681SAndroid Build Coastguard WorkerProcessInfo::ProcessInfo() : Pid(0), ReturnCode(0) {}
70*9880d681SAndroid Build Coastguard Worker
71*9880d681SAndroid Build Coastguard WorkerErrorOr<std::string> sys::findProgramByName(StringRef Name,
72*9880d681SAndroid Build Coastguard Worker                                            ArrayRef<StringRef> Paths) {
73*9880d681SAndroid Build Coastguard Worker  assert(!Name.empty() && "Must have a name!");
74*9880d681SAndroid Build Coastguard Worker  // Use the given path verbatim if it contains any slashes; this matches
75*9880d681SAndroid Build Coastguard Worker  // the behavior of sh(1) and friends.
76*9880d681SAndroid Build Coastguard Worker  if (Name.find('/') != StringRef::npos)
77*9880d681SAndroid Build Coastguard Worker    return std::string(Name);
78*9880d681SAndroid Build Coastguard Worker
79*9880d681SAndroid Build Coastguard Worker  SmallVector<StringRef, 16> EnvironmentPaths;
80*9880d681SAndroid Build Coastguard Worker  if (Paths.empty())
81*9880d681SAndroid Build Coastguard Worker    if (const char *PathEnv = std::getenv("PATH")) {
82*9880d681SAndroid Build Coastguard Worker      SplitString(PathEnv, EnvironmentPaths, ":");
83*9880d681SAndroid Build Coastguard Worker      Paths = EnvironmentPaths;
84*9880d681SAndroid Build Coastguard Worker    }
85*9880d681SAndroid Build Coastguard Worker
86*9880d681SAndroid Build Coastguard Worker  for (auto Path : Paths) {
87*9880d681SAndroid Build Coastguard Worker    if (Path.empty())
88*9880d681SAndroid Build Coastguard Worker      continue;
89*9880d681SAndroid Build Coastguard Worker
90*9880d681SAndroid Build Coastguard Worker    // Check to see if this first directory contains the executable...
91*9880d681SAndroid Build Coastguard Worker    SmallString<128> FilePath(Path);
92*9880d681SAndroid Build Coastguard Worker    sys::path::append(FilePath, Name);
93*9880d681SAndroid Build Coastguard Worker    if (sys::fs::can_execute(FilePath.c_str()))
94*9880d681SAndroid Build Coastguard Worker      return std::string(FilePath.str()); // Found the executable!
95*9880d681SAndroid Build Coastguard Worker  }
96*9880d681SAndroid Build Coastguard Worker  return errc::no_such_file_or_directory;
97*9880d681SAndroid Build Coastguard Worker}
98*9880d681SAndroid Build Coastguard Worker
99*9880d681SAndroid Build Coastguard Workerstatic bool RedirectIO(const StringRef *Path, int FD, std::string* ErrMsg) {
100*9880d681SAndroid Build Coastguard Worker  if (!Path) // Noop
101*9880d681SAndroid Build Coastguard Worker    return false;
102*9880d681SAndroid Build Coastguard Worker  std::string File;
103*9880d681SAndroid Build Coastguard Worker  if (Path->empty())
104*9880d681SAndroid Build Coastguard Worker    // Redirect empty paths to /dev/null
105*9880d681SAndroid Build Coastguard Worker    File = "/dev/null";
106*9880d681SAndroid Build Coastguard Worker  else
107*9880d681SAndroid Build Coastguard Worker    File = *Path;
108*9880d681SAndroid Build Coastguard Worker
109*9880d681SAndroid Build Coastguard Worker  // Open the file
110*9880d681SAndroid Build Coastguard Worker  int InFD = open(File.c_str(), FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666);
111*9880d681SAndroid Build Coastguard Worker  if (InFD == -1) {
112*9880d681SAndroid Build Coastguard Worker    MakeErrMsg(ErrMsg, "Cannot open file '" + File + "' for "
113*9880d681SAndroid Build Coastguard Worker              + (FD == 0 ? "input" : "output"));
114*9880d681SAndroid Build Coastguard Worker    return true;
115*9880d681SAndroid Build Coastguard Worker  }
116*9880d681SAndroid Build Coastguard Worker
117*9880d681SAndroid Build Coastguard Worker  // Install it as the requested FD
118*9880d681SAndroid Build Coastguard Worker  if (dup2(InFD, FD) == -1) {
119*9880d681SAndroid Build Coastguard Worker    MakeErrMsg(ErrMsg, "Cannot dup2");
120*9880d681SAndroid Build Coastguard Worker    close(InFD);
121*9880d681SAndroid Build Coastguard Worker    return true;
122*9880d681SAndroid Build Coastguard Worker  }
123*9880d681SAndroid Build Coastguard Worker  close(InFD);      // Close the original FD
124*9880d681SAndroid Build Coastguard Worker  return false;
125*9880d681SAndroid Build Coastguard Worker}
126*9880d681SAndroid Build Coastguard Worker
127*9880d681SAndroid Build Coastguard Worker#ifdef HAVE_POSIX_SPAWN
128*9880d681SAndroid Build Coastguard Workerstatic bool RedirectIO_PS(const std::string *Path, int FD, std::string *ErrMsg,
129*9880d681SAndroid Build Coastguard Worker                          posix_spawn_file_actions_t *FileActions) {
130*9880d681SAndroid Build Coastguard Worker  if (!Path) // Noop
131*9880d681SAndroid Build Coastguard Worker    return false;
132*9880d681SAndroid Build Coastguard Worker  const char *File;
133*9880d681SAndroid Build Coastguard Worker  if (Path->empty())
134*9880d681SAndroid Build Coastguard Worker    // Redirect empty paths to /dev/null
135*9880d681SAndroid Build Coastguard Worker    File = "/dev/null";
136*9880d681SAndroid Build Coastguard Worker  else
137*9880d681SAndroid Build Coastguard Worker    File = Path->c_str();
138*9880d681SAndroid Build Coastguard Worker
139*9880d681SAndroid Build Coastguard Worker  if (int Err = posix_spawn_file_actions_addopen(
140*9880d681SAndroid Build Coastguard Worker          FileActions, FD, File,
141*9880d681SAndroid Build Coastguard Worker          FD == 0 ? O_RDONLY : O_WRONLY | O_CREAT, 0666))
142*9880d681SAndroid Build Coastguard Worker    return MakeErrMsg(ErrMsg, "Cannot dup2", Err);
143*9880d681SAndroid Build Coastguard Worker  return false;
144*9880d681SAndroid Build Coastguard Worker}
145*9880d681SAndroid Build Coastguard Worker#endif
146*9880d681SAndroid Build Coastguard Worker
147*9880d681SAndroid Build Coastguard Workerstatic void TimeOutHandler(int Sig) {
148*9880d681SAndroid Build Coastguard Worker}
149*9880d681SAndroid Build Coastguard Worker
150*9880d681SAndroid Build Coastguard Workerstatic void SetMemoryLimits (unsigned size)
151*9880d681SAndroid Build Coastguard Worker{
152*9880d681SAndroid Build Coastguard Worker#if HAVE_SYS_RESOURCE_H && HAVE_GETRLIMIT && HAVE_SETRLIMIT
153*9880d681SAndroid Build Coastguard Worker  struct rlimit r;
154*9880d681SAndroid Build Coastguard Worker  __typeof__ (r.rlim_cur) limit = (__typeof__ (r.rlim_cur)) (size) * 1048576;
155*9880d681SAndroid Build Coastguard Worker
156*9880d681SAndroid Build Coastguard Worker  // Heap size
157*9880d681SAndroid Build Coastguard Worker  getrlimit (RLIMIT_DATA, &r);
158*9880d681SAndroid Build Coastguard Worker  r.rlim_cur = limit;
159*9880d681SAndroid Build Coastguard Worker  setrlimit (RLIMIT_DATA, &r);
160*9880d681SAndroid Build Coastguard Worker#ifdef RLIMIT_RSS
161*9880d681SAndroid Build Coastguard Worker  // Resident set size.
162*9880d681SAndroid Build Coastguard Worker  getrlimit (RLIMIT_RSS, &r);
163*9880d681SAndroid Build Coastguard Worker  r.rlim_cur = limit;
164*9880d681SAndroid Build Coastguard Worker  setrlimit (RLIMIT_RSS, &r);
165*9880d681SAndroid Build Coastguard Worker#endif
166*9880d681SAndroid Build Coastguard Worker#ifdef RLIMIT_AS  // e.g. NetBSD doesn't have it.
167*9880d681SAndroid Build Coastguard Worker  // Don't set virtual memory limit if built with any Sanitizer. They need 80Tb
168*9880d681SAndroid Build Coastguard Worker  // of virtual memory for shadow memory mapping.
169*9880d681SAndroid Build Coastguard Worker#if !LLVM_MEMORY_SANITIZER_BUILD && !LLVM_ADDRESS_SANITIZER_BUILD
170*9880d681SAndroid Build Coastguard Worker  // Virtual memory.
171*9880d681SAndroid Build Coastguard Worker  getrlimit (RLIMIT_AS, &r);
172*9880d681SAndroid Build Coastguard Worker  r.rlim_cur = limit;
173*9880d681SAndroid Build Coastguard Worker  setrlimit (RLIMIT_AS, &r);
174*9880d681SAndroid Build Coastguard Worker#endif
175*9880d681SAndroid Build Coastguard Worker#endif
176*9880d681SAndroid Build Coastguard Worker#endif
177*9880d681SAndroid Build Coastguard Worker}
178*9880d681SAndroid Build Coastguard Worker
179*9880d681SAndroid Build Coastguard Worker}
180*9880d681SAndroid Build Coastguard Worker
181*9880d681SAndroid Build Coastguard Workerstatic bool Execute(ProcessInfo &PI, StringRef Program, const char **args,
182*9880d681SAndroid Build Coastguard Worker                    const char **envp, const StringRef **redirects,
183*9880d681SAndroid Build Coastguard Worker                    unsigned memoryLimit, std::string *ErrMsg) {
184*9880d681SAndroid Build Coastguard Worker  if (!llvm::sys::fs::exists(Program)) {
185*9880d681SAndroid Build Coastguard Worker    if (ErrMsg)
186*9880d681SAndroid Build Coastguard Worker      *ErrMsg = std::string("Executable \"") + Program.str() +
187*9880d681SAndroid Build Coastguard Worker                std::string("\" doesn't exist!");
188*9880d681SAndroid Build Coastguard Worker    return false;
189*9880d681SAndroid Build Coastguard Worker  }
190*9880d681SAndroid Build Coastguard Worker
191*9880d681SAndroid Build Coastguard Worker  // If this OS has posix_spawn and there is no memory limit being implied, use
192*9880d681SAndroid Build Coastguard Worker  // posix_spawn.  It is more efficient than fork/exec.
193*9880d681SAndroid Build Coastguard Worker#ifdef HAVE_POSIX_SPAWN
194*9880d681SAndroid Build Coastguard Worker  if (memoryLimit == 0) {
195*9880d681SAndroid Build Coastguard Worker    posix_spawn_file_actions_t FileActionsStore;
196*9880d681SAndroid Build Coastguard Worker    posix_spawn_file_actions_t *FileActions = nullptr;
197*9880d681SAndroid Build Coastguard Worker
198*9880d681SAndroid Build Coastguard Worker    // If we call posix_spawn_file_actions_addopen we have to make sure the
199*9880d681SAndroid Build Coastguard Worker    // c strings we pass to it stay alive until the call to posix_spawn,
200*9880d681SAndroid Build Coastguard Worker    // so we copy any StringRefs into this variable.
201*9880d681SAndroid Build Coastguard Worker    std::string RedirectsStorage[3];
202*9880d681SAndroid Build Coastguard Worker
203*9880d681SAndroid Build Coastguard Worker    if (redirects) {
204*9880d681SAndroid Build Coastguard Worker      std::string *RedirectsStr[3] = {nullptr, nullptr, nullptr};
205*9880d681SAndroid Build Coastguard Worker      for (int I = 0; I < 3; ++I) {
206*9880d681SAndroid Build Coastguard Worker        if (redirects[I]) {
207*9880d681SAndroid Build Coastguard Worker          RedirectsStorage[I] = *redirects[I];
208*9880d681SAndroid Build Coastguard Worker          RedirectsStr[I] = &RedirectsStorage[I];
209*9880d681SAndroid Build Coastguard Worker        }
210*9880d681SAndroid Build Coastguard Worker      }
211*9880d681SAndroid Build Coastguard Worker
212*9880d681SAndroid Build Coastguard Worker      FileActions = &FileActionsStore;
213*9880d681SAndroid Build Coastguard Worker      posix_spawn_file_actions_init(FileActions);
214*9880d681SAndroid Build Coastguard Worker
215*9880d681SAndroid Build Coastguard Worker      // Redirect stdin/stdout.
216*9880d681SAndroid Build Coastguard Worker      if (RedirectIO_PS(RedirectsStr[0], 0, ErrMsg, FileActions) ||
217*9880d681SAndroid Build Coastguard Worker          RedirectIO_PS(RedirectsStr[1], 1, ErrMsg, FileActions))
218*9880d681SAndroid Build Coastguard Worker        return false;
219*9880d681SAndroid Build Coastguard Worker      if (redirects[1] == nullptr || redirects[2] == nullptr ||
220*9880d681SAndroid Build Coastguard Worker          *redirects[1] != *redirects[2]) {
221*9880d681SAndroid Build Coastguard Worker        // Just redirect stderr
222*9880d681SAndroid Build Coastguard Worker        if (RedirectIO_PS(RedirectsStr[2], 2, ErrMsg, FileActions))
223*9880d681SAndroid Build Coastguard Worker          return false;
224*9880d681SAndroid Build Coastguard Worker      } else {
225*9880d681SAndroid Build Coastguard Worker        // If stdout and stderr should go to the same place, redirect stderr
226*9880d681SAndroid Build Coastguard Worker        // to the FD already open for stdout.
227*9880d681SAndroid Build Coastguard Worker        if (int Err = posix_spawn_file_actions_adddup2(FileActions, 1, 2))
228*9880d681SAndroid Build Coastguard Worker          return !MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout", Err);
229*9880d681SAndroid Build Coastguard Worker      }
230*9880d681SAndroid Build Coastguard Worker    }
231*9880d681SAndroid Build Coastguard Worker
232*9880d681SAndroid Build Coastguard Worker    if (!envp)
233*9880d681SAndroid Build Coastguard Worker#if !USE_NSGETENVIRON
234*9880d681SAndroid Build Coastguard Worker      envp = const_cast<const char **>(environ);
235*9880d681SAndroid Build Coastguard Worker#else
236*9880d681SAndroid Build Coastguard Worker      // environ is missing in dylibs.
237*9880d681SAndroid Build Coastguard Worker      envp = const_cast<const char **>(*_NSGetEnviron());
238*9880d681SAndroid Build Coastguard Worker#endif
239*9880d681SAndroid Build Coastguard Worker
240*9880d681SAndroid Build Coastguard Worker    // Explicitly initialized to prevent what appears to be a valgrind false
241*9880d681SAndroid Build Coastguard Worker    // positive.
242*9880d681SAndroid Build Coastguard Worker    pid_t PID = 0;
243*9880d681SAndroid Build Coastguard Worker    int Err = posix_spawn(&PID, Program.str().c_str(), FileActions,
244*9880d681SAndroid Build Coastguard Worker                          /*attrp*/nullptr, const_cast<char **>(args),
245*9880d681SAndroid Build Coastguard Worker                          const_cast<char **>(envp));
246*9880d681SAndroid Build Coastguard Worker
247*9880d681SAndroid Build Coastguard Worker    if (FileActions)
248*9880d681SAndroid Build Coastguard Worker      posix_spawn_file_actions_destroy(FileActions);
249*9880d681SAndroid Build Coastguard Worker
250*9880d681SAndroid Build Coastguard Worker    if (Err)
251*9880d681SAndroid Build Coastguard Worker     return !MakeErrMsg(ErrMsg, "posix_spawn failed", Err);
252*9880d681SAndroid Build Coastguard Worker
253*9880d681SAndroid Build Coastguard Worker    PI.Pid = PID;
254*9880d681SAndroid Build Coastguard Worker
255*9880d681SAndroid Build Coastguard Worker    return true;
256*9880d681SAndroid Build Coastguard Worker  }
257*9880d681SAndroid Build Coastguard Worker#endif
258*9880d681SAndroid Build Coastguard Worker
259*9880d681SAndroid Build Coastguard Worker  // Create a child process.
260*9880d681SAndroid Build Coastguard Worker  int child = fork();
261*9880d681SAndroid Build Coastguard Worker  switch (child) {
262*9880d681SAndroid Build Coastguard Worker    // An error occurred:  Return to the caller.
263*9880d681SAndroid Build Coastguard Worker    case -1:
264*9880d681SAndroid Build Coastguard Worker      MakeErrMsg(ErrMsg, "Couldn't fork");
265*9880d681SAndroid Build Coastguard Worker      return false;
266*9880d681SAndroid Build Coastguard Worker
267*9880d681SAndroid Build Coastguard Worker    // Child process: Execute the program.
268*9880d681SAndroid Build Coastguard Worker    case 0: {
269*9880d681SAndroid Build Coastguard Worker      // Redirect file descriptors...
270*9880d681SAndroid Build Coastguard Worker      if (redirects) {
271*9880d681SAndroid Build Coastguard Worker        // Redirect stdin
272*9880d681SAndroid Build Coastguard Worker        if (RedirectIO(redirects[0], 0, ErrMsg)) { return false; }
273*9880d681SAndroid Build Coastguard Worker        // Redirect stdout
274*9880d681SAndroid Build Coastguard Worker        if (RedirectIO(redirects[1], 1, ErrMsg)) { return false; }
275*9880d681SAndroid Build Coastguard Worker        if (redirects[1] && redirects[2] &&
276*9880d681SAndroid Build Coastguard Worker            *(redirects[1]) == *(redirects[2])) {
277*9880d681SAndroid Build Coastguard Worker          // If stdout and stderr should go to the same place, redirect stderr
278*9880d681SAndroid Build Coastguard Worker          // to the FD already open for stdout.
279*9880d681SAndroid Build Coastguard Worker          if (-1 == dup2(1,2)) {
280*9880d681SAndroid Build Coastguard Worker            MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout");
281*9880d681SAndroid Build Coastguard Worker            return false;
282*9880d681SAndroid Build Coastguard Worker          }
283*9880d681SAndroid Build Coastguard Worker        } else {
284*9880d681SAndroid Build Coastguard Worker          // Just redirect stderr
285*9880d681SAndroid Build Coastguard Worker          if (RedirectIO(redirects[2], 2, ErrMsg)) { return false; }
286*9880d681SAndroid Build Coastguard Worker        }
287*9880d681SAndroid Build Coastguard Worker      }
288*9880d681SAndroid Build Coastguard Worker
289*9880d681SAndroid Build Coastguard Worker      // Set memory limits
290*9880d681SAndroid Build Coastguard Worker      if (memoryLimit!=0) {
291*9880d681SAndroid Build Coastguard Worker        SetMemoryLimits(memoryLimit);
292*9880d681SAndroid Build Coastguard Worker      }
293*9880d681SAndroid Build Coastguard Worker
294*9880d681SAndroid Build Coastguard Worker      // Execute!
295*9880d681SAndroid Build Coastguard Worker      std::string PathStr = Program;
296*9880d681SAndroid Build Coastguard Worker      if (envp != nullptr)
297*9880d681SAndroid Build Coastguard Worker        execve(PathStr.c_str(),
298*9880d681SAndroid Build Coastguard Worker               const_cast<char **>(args),
299*9880d681SAndroid Build Coastguard Worker               const_cast<char **>(envp));
300*9880d681SAndroid Build Coastguard Worker      else
301*9880d681SAndroid Build Coastguard Worker        execv(PathStr.c_str(),
302*9880d681SAndroid Build Coastguard Worker              const_cast<char **>(args));
303*9880d681SAndroid Build Coastguard Worker      // If the execve() failed, we should exit. Follow Unix protocol and
304*9880d681SAndroid Build Coastguard Worker      // return 127 if the executable was not found, and 126 otherwise.
305*9880d681SAndroid Build Coastguard Worker      // Use _exit rather than exit so that atexit functions and static
306*9880d681SAndroid Build Coastguard Worker      // object destructors cloned from the parent process aren't
307*9880d681SAndroid Build Coastguard Worker      // redundantly run, and so that any data buffered in stdio buffers
308*9880d681SAndroid Build Coastguard Worker      // cloned from the parent aren't redundantly written out.
309*9880d681SAndroid Build Coastguard Worker      _exit(errno == ENOENT ? 127 : 126);
310*9880d681SAndroid Build Coastguard Worker    }
311*9880d681SAndroid Build Coastguard Worker
312*9880d681SAndroid Build Coastguard Worker    // Parent process: Break out of the switch to do our processing.
313*9880d681SAndroid Build Coastguard Worker    default:
314*9880d681SAndroid Build Coastguard Worker      break;
315*9880d681SAndroid Build Coastguard Worker  }
316*9880d681SAndroid Build Coastguard Worker
317*9880d681SAndroid Build Coastguard Worker  PI.Pid = child;
318*9880d681SAndroid Build Coastguard Worker
319*9880d681SAndroid Build Coastguard Worker  return true;
320*9880d681SAndroid Build Coastguard Worker}
321*9880d681SAndroid Build Coastguard Worker
322*9880d681SAndroid Build Coastguard Workernamespace llvm {
323*9880d681SAndroid Build Coastguard Worker
324*9880d681SAndroid Build Coastguard WorkerProcessInfo sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait,
325*9880d681SAndroid Build Coastguard Worker                      bool WaitUntilTerminates, std::string *ErrMsg) {
326*9880d681SAndroid Build Coastguard Worker  struct sigaction Act, Old;
327*9880d681SAndroid Build Coastguard Worker  assert(PI.Pid && "invalid pid to wait on, process not started?");
328*9880d681SAndroid Build Coastguard Worker
329*9880d681SAndroid Build Coastguard Worker  int WaitPidOptions = 0;
330*9880d681SAndroid Build Coastguard Worker  pid_t ChildPid = PI.Pid;
331*9880d681SAndroid Build Coastguard Worker  if (WaitUntilTerminates) {
332*9880d681SAndroid Build Coastguard Worker    SecondsToWait = 0;
333*9880d681SAndroid Build Coastguard Worker  } else if (SecondsToWait) {
334*9880d681SAndroid Build Coastguard Worker    // Install a timeout handler.  The handler itself does nothing, but the
335*9880d681SAndroid Build Coastguard Worker    // simple fact of having a handler at all causes the wait below to return
336*9880d681SAndroid Build Coastguard Worker    // with EINTR, unlike if we used SIG_IGN.
337*9880d681SAndroid Build Coastguard Worker    memset(&Act, 0, sizeof(Act));
338*9880d681SAndroid Build Coastguard Worker    Act.sa_handler = TimeOutHandler;
339*9880d681SAndroid Build Coastguard Worker    sigemptyset(&Act.sa_mask);
340*9880d681SAndroid Build Coastguard Worker    sigaction(SIGALRM, &Act, &Old);
341*9880d681SAndroid Build Coastguard Worker    alarm(SecondsToWait);
342*9880d681SAndroid Build Coastguard Worker  } else if (SecondsToWait == 0)
343*9880d681SAndroid Build Coastguard Worker    WaitPidOptions = WNOHANG;
344*9880d681SAndroid Build Coastguard Worker
345*9880d681SAndroid Build Coastguard Worker  // Parent process: Wait for the child process to terminate.
346*9880d681SAndroid Build Coastguard Worker  int status;
347*9880d681SAndroid Build Coastguard Worker  ProcessInfo WaitResult;
348*9880d681SAndroid Build Coastguard Worker
349*9880d681SAndroid Build Coastguard Worker  do {
350*9880d681SAndroid Build Coastguard Worker    WaitResult.Pid = waitpid(ChildPid, &status, WaitPidOptions);
351*9880d681SAndroid Build Coastguard Worker  } while (WaitUntilTerminates && WaitResult.Pid == -1 && errno == EINTR);
352*9880d681SAndroid Build Coastguard Worker
353*9880d681SAndroid Build Coastguard Worker  if (WaitResult.Pid != PI.Pid) {
354*9880d681SAndroid Build Coastguard Worker    if (WaitResult.Pid == 0) {
355*9880d681SAndroid Build Coastguard Worker      // Non-blocking wait.
356*9880d681SAndroid Build Coastguard Worker      return WaitResult;
357*9880d681SAndroid Build Coastguard Worker    } else {
358*9880d681SAndroid Build Coastguard Worker      if (SecondsToWait && errno == EINTR) {
359*9880d681SAndroid Build Coastguard Worker        // Kill the child.
360*9880d681SAndroid Build Coastguard Worker        kill(PI.Pid, SIGKILL);
361*9880d681SAndroid Build Coastguard Worker
362*9880d681SAndroid Build Coastguard Worker        // Turn off the alarm and restore the signal handler
363*9880d681SAndroid Build Coastguard Worker        alarm(0);
364*9880d681SAndroid Build Coastguard Worker        sigaction(SIGALRM, &Old, nullptr);
365*9880d681SAndroid Build Coastguard Worker
366*9880d681SAndroid Build Coastguard Worker        // Wait for child to die
367*9880d681SAndroid Build Coastguard Worker        if (wait(&status) != ChildPid)
368*9880d681SAndroid Build Coastguard Worker          MakeErrMsg(ErrMsg, "Child timed out but wouldn't die");
369*9880d681SAndroid Build Coastguard Worker        else
370*9880d681SAndroid Build Coastguard Worker          MakeErrMsg(ErrMsg, "Child timed out", 0);
371*9880d681SAndroid Build Coastguard Worker
372*9880d681SAndroid Build Coastguard Worker        WaitResult.ReturnCode = -2; // Timeout detected
373*9880d681SAndroid Build Coastguard Worker        return WaitResult;
374*9880d681SAndroid Build Coastguard Worker      } else if (errno != EINTR) {
375*9880d681SAndroid Build Coastguard Worker        MakeErrMsg(ErrMsg, "Error waiting for child process");
376*9880d681SAndroid Build Coastguard Worker        WaitResult.ReturnCode = -1;
377*9880d681SAndroid Build Coastguard Worker        return WaitResult;
378*9880d681SAndroid Build Coastguard Worker      }
379*9880d681SAndroid Build Coastguard Worker    }
380*9880d681SAndroid Build Coastguard Worker  }
381*9880d681SAndroid Build Coastguard Worker
382*9880d681SAndroid Build Coastguard Worker  // We exited normally without timeout, so turn off the timer.
383*9880d681SAndroid Build Coastguard Worker  if (SecondsToWait && !WaitUntilTerminates) {
384*9880d681SAndroid Build Coastguard Worker    alarm(0);
385*9880d681SAndroid Build Coastguard Worker    sigaction(SIGALRM, &Old, nullptr);
386*9880d681SAndroid Build Coastguard Worker  }
387*9880d681SAndroid Build Coastguard Worker
388*9880d681SAndroid Build Coastguard Worker  // Return the proper exit status. Detect error conditions
389*9880d681SAndroid Build Coastguard Worker  // so we can return -1 for them and set ErrMsg informatively.
390*9880d681SAndroid Build Coastguard Worker  int result = 0;
391*9880d681SAndroid Build Coastguard Worker  if (WIFEXITED(status)) {
392*9880d681SAndroid Build Coastguard Worker    result = WEXITSTATUS(status);
393*9880d681SAndroid Build Coastguard Worker    WaitResult.ReturnCode = result;
394*9880d681SAndroid Build Coastguard Worker
395*9880d681SAndroid Build Coastguard Worker    if (result == 127) {
396*9880d681SAndroid Build Coastguard Worker      if (ErrMsg)
397*9880d681SAndroid Build Coastguard Worker        *ErrMsg = llvm::sys::StrError(ENOENT);
398*9880d681SAndroid Build Coastguard Worker      WaitResult.ReturnCode = -1;
399*9880d681SAndroid Build Coastguard Worker      return WaitResult;
400*9880d681SAndroid Build Coastguard Worker    }
401*9880d681SAndroid Build Coastguard Worker    if (result == 126) {
402*9880d681SAndroid Build Coastguard Worker      if (ErrMsg)
403*9880d681SAndroid Build Coastguard Worker        *ErrMsg = "Program could not be executed";
404*9880d681SAndroid Build Coastguard Worker      WaitResult.ReturnCode = -1;
405*9880d681SAndroid Build Coastguard Worker      return WaitResult;
406*9880d681SAndroid Build Coastguard Worker    }
407*9880d681SAndroid Build Coastguard Worker  } else if (WIFSIGNALED(status)) {
408*9880d681SAndroid Build Coastguard Worker    if (ErrMsg) {
409*9880d681SAndroid Build Coastguard Worker      *ErrMsg = strsignal(WTERMSIG(status));
410*9880d681SAndroid Build Coastguard Worker#ifdef WCOREDUMP
411*9880d681SAndroid Build Coastguard Worker      if (WCOREDUMP(status))
412*9880d681SAndroid Build Coastguard Worker        *ErrMsg += " (core dumped)";
413*9880d681SAndroid Build Coastguard Worker#endif
414*9880d681SAndroid Build Coastguard Worker    }
415*9880d681SAndroid Build Coastguard Worker    // Return a special value to indicate that the process received an unhandled
416*9880d681SAndroid Build Coastguard Worker    // signal during execution as opposed to failing to execute.
417*9880d681SAndroid Build Coastguard Worker    WaitResult.ReturnCode = -2;
418*9880d681SAndroid Build Coastguard Worker  }
419*9880d681SAndroid Build Coastguard Worker  return WaitResult;
420*9880d681SAndroid Build Coastguard Worker}
421*9880d681SAndroid Build Coastguard Worker
422*9880d681SAndroid Build Coastguard Worker  std::error_code sys::ChangeStdinToBinary(){
423*9880d681SAndroid Build Coastguard Worker  // Do nothing, as Unix doesn't differentiate between text and binary.
424*9880d681SAndroid Build Coastguard Worker    return std::error_code();
425*9880d681SAndroid Build Coastguard Worker}
426*9880d681SAndroid Build Coastguard Worker
427*9880d681SAndroid Build Coastguard Worker  std::error_code sys::ChangeStdoutToBinary(){
428*9880d681SAndroid Build Coastguard Worker  // Do nothing, as Unix doesn't differentiate between text and binary.
429*9880d681SAndroid Build Coastguard Worker    return std::error_code();
430*9880d681SAndroid Build Coastguard Worker}
431*9880d681SAndroid Build Coastguard Worker
432*9880d681SAndroid Build Coastguard Workerstd::error_code
433*9880d681SAndroid Build Coastguard Workerllvm::sys::writeFileWithEncoding(StringRef FileName, StringRef Contents,
434*9880d681SAndroid Build Coastguard Worker                                 WindowsEncodingMethod Encoding /*unused*/) {
435*9880d681SAndroid Build Coastguard Worker  std::error_code EC;
436*9880d681SAndroid Build Coastguard Worker  llvm::raw_fd_ostream OS(FileName, EC, llvm::sys::fs::OpenFlags::F_Text);
437*9880d681SAndroid Build Coastguard Worker
438*9880d681SAndroid Build Coastguard Worker  if (EC)
439*9880d681SAndroid Build Coastguard Worker    return EC;
440*9880d681SAndroid Build Coastguard Worker
441*9880d681SAndroid Build Coastguard Worker  OS << Contents;
442*9880d681SAndroid Build Coastguard Worker
443*9880d681SAndroid Build Coastguard Worker  if (OS.has_error())
444*9880d681SAndroid Build Coastguard Worker    return make_error_code(errc::io_error);
445*9880d681SAndroid Build Coastguard Worker
446*9880d681SAndroid Build Coastguard Worker  return EC;
447*9880d681SAndroid Build Coastguard Worker}
448*9880d681SAndroid Build Coastguard Worker
449*9880d681SAndroid Build Coastguard Workerbool llvm::sys::commandLineFitsWithinSystemLimits(StringRef Program, ArrayRef<const char*> Args) {
450*9880d681SAndroid Build Coastguard Worker  static long ArgMax = sysconf(_SC_ARG_MAX);
451*9880d681SAndroid Build Coastguard Worker
452*9880d681SAndroid Build Coastguard Worker  // System says no practical limit.
453*9880d681SAndroid Build Coastguard Worker  if (ArgMax == -1)
454*9880d681SAndroid Build Coastguard Worker    return true;
455*9880d681SAndroid Build Coastguard Worker
456*9880d681SAndroid Build Coastguard Worker  // Conservatively account for space required by environment variables.
457*9880d681SAndroid Build Coastguard Worker  long HalfArgMax = ArgMax / 2;
458*9880d681SAndroid Build Coastguard Worker
459*9880d681SAndroid Build Coastguard Worker  size_t ArgLength = Program.size() + 1;
460*9880d681SAndroid Build Coastguard Worker  for (ArrayRef<const char*>::iterator I = Args.begin(), E = Args.end();
461*9880d681SAndroid Build Coastguard Worker       I != E; ++I) {
462*9880d681SAndroid Build Coastguard Worker    ArgLength += strlen(*I) + 1;
463*9880d681SAndroid Build Coastguard Worker    if (ArgLength > size_t(HalfArgMax)) {
464*9880d681SAndroid Build Coastguard Worker      return false;
465*9880d681SAndroid Build Coastguard Worker    }
466*9880d681SAndroid Build Coastguard Worker  }
467*9880d681SAndroid Build Coastguard Worker  return true;
468*9880d681SAndroid Build Coastguard Worker}
469*9880d681SAndroid Build Coastguard Worker}
470