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>
37
Program::Program() : Data_(0) {}
39
Program::~Program() {}
41
unsigned Program::GetPid() const {
42
uint64_t pid = reinterpret_cast<uint64_t>(Data_);
43
return static_cast<unsigned>(pid);
46
// This function just uses the PATH environment variable to find the program.
48
Program::FindProgramByName(const std::string& progName) {
50
// Check some degenerate cases
51
if (progName.length() == 0) // no program
54
if (!temp.set(progName)) // invalid name
56
// Use the given path verbatim if it contains any slashes; this matches
57
// the behavior of sh(1) and friends.
58
if (progName.find('/') != std::string::npos)
61
// At this point, the file name does not contain slashes. Search for it
62
// through the directories specified in the PATH environment variable.
64
// Get the path. If its empty, we can't do anything to find it.
65
const char *PathStr = getenv("PATH");
69
// Now we have a colon separated list of directories to search; try them.
70
size_t PathLen = strlen(PathStr);
72
// Find the first colon...
73
const char *Colon = std::find(PathStr, PathStr+PathLen, ':');
75
// Check to see if this first directory contains the executable...
77
if (FilePath.set(std::string(PathStr,Colon))) {
78
FilePath.appendComponent(progName);
79
if (FilePath.canExecute())
80
return FilePath; // Found the executable!
83
// Nope it wasn't in this directory, check the next path in the list!
84
PathLen -= Colon-PathStr;
87
// Advance past duplicate colons
88
while (*PathStr == ':') {
96
static bool RedirectIO(const Path *Path, int FD, std::string* ErrMsg) {
102
// Redirect empty paths to /dev/null
108
int InFD = open(File.c_str(), FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666);
110
MakeErrMsg(ErrMsg, "Cannot open file '" + File + "' for "
111
+ (FD == 0 ? "input" : "output"));
115
// Install it as the requested FD
116
if (-1 == dup2(InFD, FD)) {
117
MakeErrMsg(ErrMsg, "Cannot dup2");
120
close(InFD); // Close the original FD
124
static void TimeOutHandler(int Sig) {
127
static void SetMemoryLimits (unsigned size)
129
#if HAVE_SYS_RESOURCE_H && HAVE_GETRLIMIT && HAVE_SETRLIMIT
131
__typeof__ (r.rlim_cur) limit = (__typeof__ (r.rlim_cur)) (size) * 1048576;
134
getrlimit (RLIMIT_DATA, &r);
136
setrlimit (RLIMIT_DATA, &r);
138
// Resident set size.
139
getrlimit (RLIMIT_RSS, &r);
141
setrlimit (RLIMIT_RSS, &r);
143
#ifdef RLIMIT_AS // e.g. NetBSD doesn't have it.
145
getrlimit (RLIMIT_AS, &r);
147
setrlimit (RLIMIT_AS, &r);
153
Program::Execute(const Path& path,
156
const Path** redirects,
157
unsigned memoryLimit,
160
if (!path.canExecute()) {
162
*ErrMsg = path.str() + " is not executable";
166
// Create a child process.
169
// An error occured: Return to the caller.
171
MakeErrMsg(ErrMsg, "Couldn't fork");
174
// Child process: Execute the program.
176
// Redirect file descriptors...
179
if (RedirectIO(redirects[0], 0, ErrMsg)) { return false; }
181
if (RedirectIO(redirects[1], 1, ErrMsg)) { return false; }
182
if (redirects[1] && redirects[2] &&
183
*(redirects[1]) == *(redirects[2])) {
184
// If stdout and stderr should go to the same place, redirect stderr
185
// to the FD already open for stdout.
186
if (-1 == dup2(1,2)) {
187
MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout");
191
// Just redirect stderr
192
if (RedirectIO(redirects[2], 2, ErrMsg)) { return false; }
197
if (memoryLimit!=0) {
198
SetMemoryLimits(memoryLimit);
203
execve(path.c_str(), (char**)args, (char**)envp);
205
execv(path.c_str(), (char**)args);
206
// If the execve() failed, we should exit. Follow Unix protocol and
207
// return 127 if the executable was not found, and 126 otherwise.
208
// Use _exit rather than exit so that atexit functions and static
209
// object destructors cloned from the parent process aren't
210
// redundantly run, and so that any data buffered in stdio buffers
211
// cloned from the parent aren't redundantly written out.
212
_exit(errno == ENOENT ? 127 : 126);
215
// Parent process: Break out of the switch to do our processing.
220
Data_ = reinterpret_cast<void*>(child);
226
Program::Wait(unsigned secondsToWait,
229
#ifdef HAVE_SYS_WAIT_H
230
struct sigaction Act, Old;
233
MakeErrMsg(ErrMsg, "Process not started!");
237
// Install a timeout handler. The handler itself does nothing, but the simple
238
// fact of having a handler at all causes the wait below to return with EINTR,
239
// unlike if we used SIG_IGN.
241
Act.sa_sigaction = 0;
242
Act.sa_handler = TimeOutHandler;
243
sigemptyset(&Act.sa_mask);
245
sigaction(SIGALRM, &Act, &Old);
246
alarm(secondsToWait);
249
// Parent process: Wait for the child process to terminate.
251
uint64_t pid = reinterpret_cast<uint64_t>(Data_);
252
pid_t child = static_cast<pid_t>(pid);
253
while (waitpid(pid, &status, 0) != child)
254
if (secondsToWait && errno == EINTR) {
256
kill(child, SIGKILL);
258
// Turn off the alarm and restore the signal handler
260
sigaction(SIGALRM, &Old, 0);
262
// Wait for child to die
263
if (wait(&status) != child)
264
MakeErrMsg(ErrMsg, "Child timed out but wouldn't die");
266
MakeErrMsg(ErrMsg, "Child timed out", 0);
268
return -1; // Timeout detected
269
} else if (errno != EINTR) {
270
MakeErrMsg(ErrMsg, "Error waiting for child process");
274
// We exited normally without timeout, so turn off the timer.
277
sigaction(SIGALRM, &Old, 0);
280
// Return the proper exit status. 0=success, >0 is programs' exit status,
281
// <0 means a signal was returned, -9999999 means the program dumped core.
283
if (WIFEXITED(status))
284
result = WEXITSTATUS(status);
285
else if (WIFSIGNALED(status))
286
result = 0 - WTERMSIG(status);
288
else if (WCOREDUMP(status))
289
result |= 0x01000000;
299
Program::Kill(std::string* ErrMsg) {
301
MakeErrMsg(ErrMsg, "Process not started!");
305
uint64_t pid64 = reinterpret_cast<uint64_t>(Data_);
306
pid_t pid = static_cast<pid_t>(pid64);
308
if (kill(pid, SIGKILL) != 0) {
309
MakeErrMsg(ErrMsg, "The process couldn't be killed!");
316
bool Program::ChangeStdinToBinary(){
317
// Do nothing, as Unix doesn't differentiate between text and binary.
321
bool Program::ChangeStdoutToBinary(){
322
// Do nothing, as Unix doesn't differentiate between text and binary.
326
bool Program::ChangeStderrToBinary(){
327
// Do nothing, as Unix doesn't differentiate between text and binary.