LLVM API Documentation

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