1 //===- llvm/System/Unix/Program.cpp -----------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the Unix specific portion of the Program class.
12 //===----------------------------------------------------------------------===//
14 //===----------------------------------------------------------------------===//
15 //=== WARNING: Implementation here must contain only generic UNIX code that
16 //=== is guaranteed to work on *all* UNIX variants.
17 //===----------------------------------------------------------------------===//
19 #include <llvm/Config/config.h>
24 #if HAVE_SYS_RESOURCE_H
25 #include <sys/resource.h>
33 #ifdef HAVE_POSIX_SPAWN
37 extern char **environ;
42 Program::Program() : Data_(0) {}
44 Program::~Program() {}
46 unsigned Program::GetPid() const {
47 uint64_t pid = reinterpret_cast<uint64_t>(Data_);
48 return static_cast<unsigned>(pid);
51 // This function just uses the PATH environment variable to find the program.
53 Program::FindProgramByName(const std::string& progName) {
55 // Check some degenerate cases
56 if (progName.length() == 0) // no program
59 if (!temp.set(progName)) // invalid name
61 // Use the given path verbatim if it contains any slashes; this matches
62 // the behavior of sh(1) and friends.
63 if (progName.find('/') != std::string::npos)
66 // At this point, the file name does not contain slashes. Search for it
67 // through the directories specified in the PATH environment variable.
69 // Get the path. If its empty, we can't do anything to find it.
70 const char *PathStr = getenv("PATH");
74 // Now we have a colon separated list of directories to search; try them.
75 size_t PathLen = strlen(PathStr);
77 // Find the first colon...
78 const char *Colon = std::find(PathStr, PathStr+PathLen, ':');
80 // Check to see if this first directory contains the executable...
82 if (FilePath.set(std::string(PathStr,Colon))) {
83 FilePath.appendComponent(progName);
84 if (FilePath.canExecute())
85 return FilePath; // Found the executable!
88 // Nope it wasn't in this directory, check the next path in the list!
89 PathLen -= Colon-PathStr;
92 // Advance past duplicate colons
93 while (*PathStr == ':') {
101 static bool RedirectIO(const Path *Path, int FD, std::string* ErrMsg) {
102 if (Path == 0) // Noop
106 // Redirect empty paths to /dev/null
112 int InFD = open(File.c_str(), FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666);
114 MakeErrMsg(ErrMsg, "Cannot open file '" + File + "' for "
115 + (FD == 0 ? "input" : "output"));
119 // Install it as the requested FD
120 if (dup2(InFD, FD) == -1) {
121 MakeErrMsg(ErrMsg, "Cannot dup2");
125 close(InFD); // Close the original FD
129 #ifdef HAVE_POSIX_SPAWN
130 static bool RedirectIO_PS(const Path *Path, int FD, std::string *ErrMsg,
131 posix_spawn_file_actions_t &FileActions) {
132 if (Path == 0) // Noop
136 // Redirect empty paths to /dev/null
141 if (int Err = posix_spawn_file_actions_addopen(&FileActions, FD,
142 File.c_str(), FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666))
143 return MakeErrMsg(ErrMsg, "Cannot dup2", Err);
148 static void TimeOutHandler(int Sig) {
151 static void SetMemoryLimits (unsigned size)
153 #if HAVE_SYS_RESOURCE_H && HAVE_GETRLIMIT && HAVE_SETRLIMIT
155 __typeof__ (r.rlim_cur) limit = (__typeof__ (r.rlim_cur)) (size) * 1048576;
158 getrlimit (RLIMIT_DATA, &r);
160 setrlimit (RLIMIT_DATA, &r);
162 // Resident set size.
163 getrlimit (RLIMIT_RSS, &r);
165 setrlimit (RLIMIT_RSS, &r);
167 #ifdef RLIMIT_AS // e.g. NetBSD doesn't have it.
169 getrlimit (RLIMIT_AS, &r);
171 setrlimit (RLIMIT_AS, &r);
177 Program::Execute(const Path &path, const char **args, const char **envp,
178 const Path **redirects, unsigned memoryLimit,
179 std::string *ErrMsg) {
180 // If this OS has posix_spawn and there is no memory limit being implied, use
181 // posix_spawn. It is more efficient than fork/exec.
182 #ifdef HAVE_POSIX_SPAWN
183 if (memoryLimit == 0) {
184 posix_spawn_file_actions_t FileActions;
185 posix_spawn_file_actions_init(&FileActions);
188 // Redirect stdin/stdout.
189 if (RedirectIO_PS(redirects[0], 0, ErrMsg, FileActions) ||
190 RedirectIO_PS(redirects[1], 1, ErrMsg, FileActions))
192 if (redirects[1] == 0 || redirects[2] == 0 ||
193 *redirects[1] != *redirects[2]) {
194 // Just redirect stderr
195 if (RedirectIO_PS(redirects[2], 2, ErrMsg, FileActions)) return false;
197 // If stdout and stderr should go to the same place, redirect stderr
198 // to the FD already open for stdout.
199 if (int Err = posix_spawn_file_actions_adddup2(&FileActions, 1, 2))
200 return !MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout", Err);
205 if (!envp) envp = (const char**)environ;
206 int Err = posix_spawn(&PID, path.c_str(), &FileActions,
207 /*attrp*/0, (char**)args, (char**)envp);
209 posix_spawn_file_actions_destroy(&FileActions);
212 return !MakeErrMsg(ErrMsg, "posix_spawn failed", Err);
214 Data_ = reinterpret_cast<void*>(PID);
219 if (!path.canExecute()) {
221 *ErrMsg = path.str() + " is not executable";
225 // Create a child process.
228 // An error occured: Return to the caller.
230 MakeErrMsg(ErrMsg, "Couldn't fork");
233 // Child process: Execute the program.
235 // Redirect file descriptors...
238 if (RedirectIO(redirects[0], 0, ErrMsg)) { return false; }
240 if (RedirectIO(redirects[1], 1, ErrMsg)) { return false; }
241 if (redirects[1] && redirects[2] &&
242 *(redirects[1]) == *(redirects[2])) {
243 // If stdout and stderr should go to the same place, redirect stderr
244 // to the FD already open for stdout.
245 if (-1 == dup2(1,2)) {
246 MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout");
250 // Just redirect stderr
251 if (RedirectIO(redirects[2], 2, ErrMsg)) { return false; }
256 if (memoryLimit!=0) {
257 SetMemoryLimits(memoryLimit);
262 execve(path.c_str(), (char**)args, (char**)envp);
264 execv(path.c_str(), (char**)args);
265 // If the execve() failed, we should exit. Follow Unix protocol and
266 // return 127 if the executable was not found, and 126 otherwise.
267 // Use _exit rather than exit so that atexit functions and static
268 // object destructors cloned from the parent process aren't
269 // redundantly run, and so that any data buffered in stdio buffers
270 // cloned from the parent aren't redundantly written out.
271 _exit(errno == ENOENT ? 127 : 126);
274 // Parent process: Break out of the switch to do our processing.
279 Data_ = reinterpret_cast<void*>(child);
285 Program::Wait(unsigned secondsToWait,
288 #ifdef HAVE_SYS_WAIT_H
289 struct sigaction Act, Old;
292 MakeErrMsg(ErrMsg, "Process not started!");
296 // Install a timeout handler. The handler itself does nothing, but the simple
297 // fact of having a handler at all causes the wait below to return with EINTR,
298 // unlike if we used SIG_IGN.
301 Act.sa_sigaction = 0;
303 Act.sa_handler = TimeOutHandler;
304 sigemptyset(&Act.sa_mask);
306 sigaction(SIGALRM, &Act, &Old);
307 alarm(secondsToWait);
310 // Parent process: Wait for the child process to terminate.
312 uint64_t pid = reinterpret_cast<uint64_t>(Data_);
313 pid_t child = static_cast<pid_t>(pid);
314 while (waitpid(pid, &status, 0) != child)
315 if (secondsToWait && errno == EINTR) {
317 kill(child, SIGKILL);
319 // Turn off the alarm and restore the signal handler
321 sigaction(SIGALRM, &Old, 0);
323 // Wait for child to die
324 if (wait(&status) != child)
325 MakeErrMsg(ErrMsg, "Child timed out but wouldn't die");
327 MakeErrMsg(ErrMsg, "Child timed out", 0);
329 return -1; // Timeout detected
330 } else if (errno != EINTR) {
331 MakeErrMsg(ErrMsg, "Error waiting for child process");
335 // We exited normally without timeout, so turn off the timer.
338 sigaction(SIGALRM, &Old, 0);
341 // Return the proper exit status. 0=success, >0 is programs' exit status,
342 // <0 means a signal was returned, -9999999 means the program dumped core.
344 if (WIFEXITED(status))
345 result = WEXITSTATUS(status);
346 else if (WIFSIGNALED(status))
347 result = 0 - WTERMSIG(status);
349 else if (WCOREDUMP(status))
350 result |= 0x01000000;
360 Program::Kill(std::string* ErrMsg) {
362 MakeErrMsg(ErrMsg, "Process not started!");
366 uint64_t pid64 = reinterpret_cast<uint64_t>(Data_);
367 pid_t pid = static_cast<pid_t>(pid64);
369 if (kill(pid, SIGKILL) != 0) {
370 MakeErrMsg(ErrMsg, "The process couldn't be killed!");
377 bool Program::ChangeStdinToBinary(){
378 // Do nothing, as Unix doesn't differentiate between text and binary.
382 bool Program::ChangeStdoutToBinary(){
383 // Do nothing, as Unix doesn't differentiate between text and binary.
387 bool Program::ChangeStderrToBinary(){
388 // Do nothing, as Unix doesn't differentiate between text and binary.