LLVM  8.0.1
Program.inc
Go to the documentation of this file.
1 //===- llvm/Support/Unix/Program.cpp -----------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the Unix specific portion of the Program class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 //===----------------------------------------------------------------------===//
15 //=== WARNING: Implementation here must contain only generic UNIX code that
16 //=== is guaranteed to work on *all* UNIX variants.
17 //===----------------------------------------------------------------------===//
18 
19 #include "Unix.h"
20 #include "llvm/ADT/StringExtras.h"
21 #include "llvm/Config/config.h"
22 #include "llvm/Support/Compiler.h"
23 #include "llvm/Support/Errc.h"
25 #include "llvm/Support/Path.h"
28 #if HAVE_SYS_STAT_H
29 #include <sys/stat.h>
30 #endif
31 #if HAVE_SYS_RESOURCE_H
32 #include <sys/resource.h>
33 #endif
34 #if HAVE_SIGNAL_H
35 #include <signal.h>
36 #endif
37 #if HAVE_FCNTL_H
38 #include <fcntl.h>
39 #endif
40 #if HAVE_UNISTD_H
41 #include <unistd.h>
42 #endif
43 #ifdef HAVE_POSIX_SPAWN
44 #include <spawn.h>
45 
46 #if defined(__APPLE__)
47 #include <TargetConditionals.h>
48 #endif
49 
50 #if defined(__APPLE__) && !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)
51 #define USE_NSGETENVIRON 1
52 #else
53 #define USE_NSGETENVIRON 0
54 #endif
55 
56 #if !USE_NSGETENVIRON
57  extern char **environ;
58 #else
59 #include <crt_externs.h> // _NSGetEnviron
60 #endif
61 #endif
62 
63 namespace llvm {
64 
65 using namespace sys;
66 
67 ProcessInfo::ProcessInfo() : Pid(0), ReturnCode(0) {}
68 
69 ErrorOr<std::string> sys::findProgramByName(StringRef Name,
70  ArrayRef<StringRef> Paths) {
71  assert(!Name.empty() && "Must have a name!");
72  // Use the given path verbatim if it contains any slashes; this matches
73  // the behavior of sh(1) and friends.
74  if (Name.find('/') != StringRef::npos)
75  return std::string(Name);
76 
77  SmallVector<StringRef, 16> EnvironmentPaths;
78  if (Paths.empty())
79  if (const char *PathEnv = std::getenv("PATH")) {
80  SplitString(PathEnv, EnvironmentPaths, ":");
81  Paths = EnvironmentPaths;
82  }
83 
84  for (auto Path : Paths) {
85  if (Path.empty())
86  continue;
87 
88  // Check to see if this first directory contains the executable...
89  SmallString<128> FilePath(Path);
90  sys::path::append(FilePath, Name);
91  if (sys::fs::can_execute(FilePath.c_str()))
92  return std::string(FilePath.str()); // Found the executable!
93  }
95 }
96 
97 static bool RedirectIO(Optional<StringRef> Path, int FD, std::string* ErrMsg) {
98  if (!Path) // Noop
99  return false;
100  std::string File;
101  if (Path->empty())
102  // Redirect empty paths to /dev/null
103  File = "/dev/null";
104  else
105  File = *Path;
106 
107  // Open the file
108  int InFD = open(File.c_str(), FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666);
109  if (InFD == -1) {
110  MakeErrMsg(ErrMsg, "Cannot open file '" + File + "' for "
111  + (FD == 0 ? "input" : "output"));
112  return true;
113  }
114 
115  // Install it as the requested FD
116  if (dup2(InFD, FD) == -1) {
117  MakeErrMsg(ErrMsg, "Cannot dup2");
118  close(InFD);
119  return true;
120  }
121  close(InFD); // Close the original FD
122  return false;
123 }
124 
125 #ifdef HAVE_POSIX_SPAWN
126 static bool RedirectIO_PS(const std::string *Path, int FD, std::string *ErrMsg,
127  posix_spawn_file_actions_t *FileActions) {
128  if (!Path) // Noop
129  return false;
130  const char *File;
131  if (Path->empty())
132  // Redirect empty paths to /dev/null
133  File = "/dev/null";
134  else
135  File = Path->c_str();
136 
137  if (int Err = posix_spawn_file_actions_addopen(
138  FileActions, FD, File,
139  FD == 0 ? O_RDONLY : O_WRONLY | O_CREAT, 0666))
140  return MakeErrMsg(ErrMsg, "Cannot dup2", Err);
141  return false;
142 }
143 #endif
144 
145 static void TimeOutHandler(int Sig) {
146 }
147 
148 static void SetMemoryLimits(unsigned size) {
149 #if HAVE_SYS_RESOURCE_H && HAVE_GETRLIMIT && HAVE_SETRLIMIT
150  struct rlimit r;
151  __typeof__ (r.rlim_cur) limit = (__typeof__ (r.rlim_cur)) (size) * 1048576;
152 
153  // Heap size
154  getrlimit (RLIMIT_DATA, &r);
155  r.rlim_cur = limit;
156  setrlimit (RLIMIT_DATA, &r);
157 #ifdef RLIMIT_RSS
158  // Resident set size.
159  getrlimit (RLIMIT_RSS, &r);
160  r.rlim_cur = limit;
161  setrlimit (RLIMIT_RSS, &r);
162 #endif
163 #endif
164 }
165 
166 }
167 
168 static std::vector<const char *>
169 toNullTerminatedCStringArray(ArrayRef<StringRef> Strings, StringSaver &Saver) {
170  std::vector<const char *> Result;
171  for (StringRef S : Strings)
172  Result.push_back(Saver.save(S).data());
173  Result.push_back(nullptr);
174  return Result;
175 }
176 
177 static bool Execute(ProcessInfo &PI, StringRef Program,
178  ArrayRef<StringRef> Args, Optional<ArrayRef<StringRef>> Env,
179  ArrayRef<Optional<StringRef>> Redirects,
180  unsigned MemoryLimit, std::string *ErrMsg) {
181  if (!llvm::sys::fs::exists(Program)) {
182  if (ErrMsg)
183  *ErrMsg = std::string("Executable \"") + Program.str() +
184  std::string("\" doesn't exist!");
185  return false;
186  }
187 
189  StringSaver Saver(Allocator);
190  std::vector<const char *> ArgVector, EnvVector;
191  const char **Argv = nullptr;
192  const char **Envp = nullptr;
193  ArgVector = toNullTerminatedCStringArray(Args, Saver);
194  Argv = ArgVector.data();
195  if (Env) {
196  EnvVector = toNullTerminatedCStringArray(*Env, Saver);
197  Envp = EnvVector.data();
198  }
199 
200  // If this OS has posix_spawn and there is no memory limit being implied, use
201  // posix_spawn. It is more efficient than fork/exec.
202 #ifdef HAVE_POSIX_SPAWN
203  if (MemoryLimit == 0) {
204  posix_spawn_file_actions_t FileActionsStore;
205  posix_spawn_file_actions_t *FileActions = nullptr;
206 
207  // If we call posix_spawn_file_actions_addopen we have to make sure the
208  // c strings we pass to it stay alive until the call to posix_spawn,
209  // so we copy any StringRefs into this variable.
210  std::string RedirectsStorage[3];
211 
212  if (!Redirects.empty()) {
213  assert(Redirects.size() == 3);
214  std::string *RedirectsStr[3] = {nullptr, nullptr, nullptr};
215  for (int I = 0; I < 3; ++I) {
216  if (Redirects[I]) {
217  RedirectsStorage[I] = *Redirects[I];
218  RedirectsStr[I] = &RedirectsStorage[I];
219  }
220  }
221 
222  FileActions = &FileActionsStore;
223  posix_spawn_file_actions_init(FileActions);
224 
225  // Redirect stdin/stdout.
226  if (RedirectIO_PS(RedirectsStr[0], 0, ErrMsg, FileActions) ||
227  RedirectIO_PS(RedirectsStr[1], 1, ErrMsg, FileActions))
228  return false;
229  if (!Redirects[1] || !Redirects[2] || *Redirects[1] != *Redirects[2]) {
230  // Just redirect stderr
231  if (RedirectIO_PS(RedirectsStr[2], 2, ErrMsg, FileActions))
232  return false;
233  } else {
234  // If stdout and stderr should go to the same place, redirect stderr
235  // to the FD already open for stdout.
236  if (int Err = posix_spawn_file_actions_adddup2(FileActions, 1, 2))
237  return !MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout", Err);
238  }
239  }
240 
241  if (!Envp)
242 #if !USE_NSGETENVIRON
243  Envp = const_cast<const char **>(environ);
244 #else
245  // environ is missing in dylibs.
246  Envp = const_cast<const char **>(*_NSGetEnviron());
247 #endif
248 
249  // Explicitly initialized to prevent what appears to be a valgrind false
250  // positive.
251  pid_t PID = 0;
252  int Err = posix_spawn(&PID, Program.str().c_str(), FileActions,
253  /*attrp*/ nullptr, const_cast<char **>(Argv),
254  const_cast<char **>(Envp));
255 
256  if (FileActions)
257  posix_spawn_file_actions_destroy(FileActions);
258 
259  if (Err)
260  return !MakeErrMsg(ErrMsg, "posix_spawn failed", Err);
261 
262  PI.Pid = PID;
263  PI.Process = PID;
264 
265  return true;
266  }
267 #endif
268 
269  // Create a child process.
270  int child = fork();
271  switch (child) {
272  // An error occurred: Return to the caller.
273  case -1:
274  MakeErrMsg(ErrMsg, "Couldn't fork");
275  return false;
276 
277  // Child process: Execute the program.
278  case 0: {
279  // Redirect file descriptors...
280  if (!Redirects.empty()) {
281  // Redirect stdin
282  if (RedirectIO(Redirects[0], 0, ErrMsg)) { return false; }
283  // Redirect stdout
284  if (RedirectIO(Redirects[1], 1, ErrMsg)) { return false; }
285  if (Redirects[1] && Redirects[2] && *Redirects[1] == *Redirects[2]) {
286  // If stdout and stderr should go to the same place, redirect stderr
287  // to the FD already open for stdout.
288  if (-1 == dup2(1,2)) {
289  MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout");
290  return false;
291  }
292  } else {
293  // Just redirect stderr
294  if (RedirectIO(Redirects[2], 2, ErrMsg)) { return false; }
295  }
296  }
297 
298  // Set memory limits
299  if (MemoryLimit!=0) {
300  SetMemoryLimits(MemoryLimit);
301  }
302 
303  // Execute!
304  std::string PathStr = Program;
305  if (Envp != nullptr)
306  execve(PathStr.c_str(), const_cast<char **>(Argv),
307  const_cast<char **>(Envp));
308  else
309  execv(PathStr.c_str(), const_cast<char **>(Argv));
310  // If the execve() failed, we should exit. Follow Unix protocol and
311  // return 127 if the executable was not found, and 126 otherwise.
312  // Use _exit rather than exit so that atexit functions and static
313  // object destructors cloned from the parent process aren't
314  // redundantly run, and so that any data buffered in stdio buffers
315  // cloned from the parent aren't redundantly written out.
316  _exit(errno == ENOENT ? 127 : 126);
317  }
318 
319  // Parent process: Break out of the switch to do our processing.
320  default:
321  break;
322  }
323 
324  PI.Pid = child;
325  PI.Process = child;
326 
327  return true;
328 }
329 
330 namespace llvm {
331 
332 ProcessInfo sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait,
333  bool WaitUntilTerminates, std::string *ErrMsg) {
334  struct sigaction Act, Old;
335  assert(PI.Pid && "invalid pid to wait on, process not started?");
336 
337  int WaitPidOptions = 0;
338  pid_t ChildPid = PI.Pid;
339  if (WaitUntilTerminates) {
340  SecondsToWait = 0;
341  } else if (SecondsToWait) {
342  // Install a timeout handler. The handler itself does nothing, but the
343  // simple fact of having a handler at all causes the wait below to return
344  // with EINTR, unlike if we used SIG_IGN.
345  memset(&Act, 0, sizeof(Act));
346  Act.sa_handler = TimeOutHandler;
347  sigemptyset(&Act.sa_mask);
348  sigaction(SIGALRM, &Act, &Old);
349  alarm(SecondsToWait);
350  } else if (SecondsToWait == 0)
351  WaitPidOptions = WNOHANG;
352 
353  // Parent process: Wait for the child process to terminate.
354  int status;
355  ProcessInfo WaitResult;
356 
357  do {
358  WaitResult.Pid = waitpid(ChildPid, &status, WaitPidOptions);
359  } while (WaitUntilTerminates && WaitResult.Pid == -1 && errno == EINTR);
360 
361  if (WaitResult.Pid != PI.Pid) {
362  if (WaitResult.Pid == 0) {
363  // Non-blocking wait.
364  return WaitResult;
365  } else {
366  if (SecondsToWait && errno == EINTR) {
367  // Kill the child.
368  kill(PI.Pid, SIGKILL);
369 
370  // Turn off the alarm and restore the signal handler
371  alarm(0);
372  sigaction(SIGALRM, &Old, nullptr);
373 
374  // Wait for child to die
375  if (wait(&status) != ChildPid)
376  MakeErrMsg(ErrMsg, "Child timed out but wouldn't die");
377  else
378  MakeErrMsg(ErrMsg, "Child timed out", 0);
379 
380  WaitResult.ReturnCode = -2; // Timeout detected
381  return WaitResult;
382  } else if (errno != EINTR) {
383  MakeErrMsg(ErrMsg, "Error waiting for child process");
384  WaitResult.ReturnCode = -1;
385  return WaitResult;
386  }
387  }
388  }
389 
390  // We exited normally without timeout, so turn off the timer.
391  if (SecondsToWait && !WaitUntilTerminates) {
392  alarm(0);
393  sigaction(SIGALRM, &Old, nullptr);
394  }
395 
396  // Return the proper exit status. Detect error conditions
397  // so we can return -1 for them and set ErrMsg informatively.
398  int result = 0;
399  if (WIFEXITED(status)) {
400  result = WEXITSTATUS(status);
401  WaitResult.ReturnCode = result;
402 
403  if (result == 127) {
404  if (ErrMsg)
405  *ErrMsg = llvm::sys::StrError(ENOENT);
406  WaitResult.ReturnCode = -1;
407  return WaitResult;
408  }
409  if (result == 126) {
410  if (ErrMsg)
411  *ErrMsg = "Program could not be executed";
412  WaitResult.ReturnCode = -1;
413  return WaitResult;
414  }
415  } else if (WIFSIGNALED(status)) {
416  if (ErrMsg) {
417  *ErrMsg = strsignal(WTERMSIG(status));
418 #ifdef WCOREDUMP
419  if (WCOREDUMP(status))
420  *ErrMsg += " (core dumped)";
421 #endif
422  }
423  // Return a special value to indicate that the process received an unhandled
424  // signal during execution as opposed to failing to execute.
425  WaitResult.ReturnCode = -2;
426  }
427  return WaitResult;
428 }
429 
430 std::error_code sys::ChangeStdinToBinary() {
431  // Do nothing, as Unix doesn't differentiate between text and binary.
432  return std::error_code();
433 }
434 
435 std::error_code sys::ChangeStdoutToBinary() {
436  // Do nothing, as Unix doesn't differentiate between text and binary.
437  return std::error_code();
438 }
439 
440 std::error_code
441 llvm::sys::writeFileWithEncoding(StringRef FileName, StringRef Contents,
442  WindowsEncodingMethod Encoding /*unused*/) {
443  std::error_code EC;
445 
446  if (EC)
447  return EC;
448 
449  OS << Contents;
450 
451  if (OS.has_error())
453 
454  return EC;
455 }
456 
457 bool llvm::sys::commandLineFitsWithinSystemLimits(StringRef Program,
458  ArrayRef<StringRef> Args) {
459  static long ArgMax = sysconf(_SC_ARG_MAX);
460  // POSIX requires that _POSIX_ARG_MAX is 4096, which is the lowest possible
461  // value for ARG_MAX on a POSIX compliant system.
462  static long ArgMin = _POSIX_ARG_MAX;
463 
464  // This the same baseline used by xargs.
465  long EffectiveArgMax = 128 * 1024;
466 
467  if (EffectiveArgMax > ArgMax)
468  EffectiveArgMax = ArgMax;
469  else if (EffectiveArgMax < ArgMin)
470  EffectiveArgMax = ArgMin;
471 
472  // System says no practical limit.
473  if (ArgMax == -1)
474  return true;
475 
476  // Conservatively account for space required by environment variables.
477  long HalfArgMax = EffectiveArgMax / 2;
478 
479  size_t ArgLength = Program.size() + 1;
480  for (StringRef Arg : Args) {
481  // Ensure that we do not exceed the MAX_ARG_STRLEN constant on Linux, which
482  // does not have a constant unlike what the man pages would have you
483  // believe. Since this limit is pretty high, perform the check
484  // unconditionally rather than trying to be aggressive and limiting it to
485  // Linux only.
486  if (Arg.size() >= (32 * 4096))
487  return false;
488 
489  ArgLength += Arg.size() + 1;
490  if (ArgLength > size_t(HalfArgMax)) {
491  return false;
492  }
493  }
494 
495  return true;
496 }
497 }
bool can_execute(const Twine &Path)
Can we execute this file?
This class represents lattice values for constants.
Definition: AllocatorList.h:24
std::error_code ChangeStdoutToBinary()
ErrorOr< std::string > findProgramByName(StringRef Name, ArrayRef< StringRef > Paths={})
Find the first executable file Name in Paths.
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:480
amdgpu Simplify well known AMD library false Value Value const Twine & Name
std::string StrError()
Returns a string representation of the errno value, using whatever thread-safe variant of strerror() ...
Definition: Errno.cpp:32
std::error_code make_error_code(BitcodeError E)
void SplitString(StringRef Source, SmallVectorImpl< StringRef > &OutFragments, StringRef Delimiters=" \\\)
SplitString - Split up the specified string according to the specified delimiters, appending the result fragments to the output list.
BumpPtrAllocatorImpl BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition: Allocator.h:435
std::error_code status(const Twine &path, file_status &result, bool follow=true)
Get file status as if by POSIX stat().
bool commandLineFitsWithinSystemLimits(StringRef Program, ArrayRef< StringRef > Args)
Return true if the given arguments fit within system-specific argument length limits.
Basic Register Allocator
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
Definition: STLExtras.h:1167
std::error_code writeFileWithEncoding(StringRef FileName, StringRef Contents, WindowsEncodingMethod Encoding=WEM_UTF8)
Saves the UTF8-encoded contents string into the file FileName using a specific encoding.
bool MakeErrMsg(std::string *ErrMsg, const std::string &prefix)
WindowsEncodingMethod
File encoding options when writing contents that a non-UTF8 tool will read (on Windows systems)...
Definition: Program.h:146
std::error_code ChangeStdinToBinary()
amdgpu Simplify well known AMD library false Value Value * Arg
A raw_ostream that writes to a file descriptor.
Definition: raw_ostream.h:366
static const size_t npos
Definition: StringRef.h:51
#define I(x, y, z)
Definition: MD5.cpp:58
static bool Execute(ProcessInfo &PI, StringRef Program, ArrayRef< StringRef > Args, Optional< ArrayRef< StringRef >> Env, ArrayRef< Optional< StringRef >> Redirects, unsigned MemoryLimit, std::string *ErrMsg)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ProcessInfo Wait(const ProcessInfo &PI, unsigned SecondsToWait, bool WaitUntilTerminates, std::string *ErrMsg=nullptr)
This function waits for the process specified by PI to finish.
bool exists(const basic_file_status &status)
Does file exist?
Definition: Path.cpp:1022
constexpr char Args[]
Key for Kernel::Metadata::mArgs.