This is horrible. Split the difference, and declare 'environ' on all non-Darwin
[oota-llvm.git] / lib / System / Unix / Program.inc
1 //===- llvm/System/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 <llvm/Config/config.h>
20 #include "Unix.h"
21 #if HAVE_SYS_STAT_H
22 #include <sys/stat.h>
23 #endif
24 #if HAVE_SYS_RESOURCE_H
25 #include <sys/resource.h>
26 #endif
27 #if HAVE_SIGNAL_H
28 #include <signal.h>
29 #endif
30 #if HAVE_FCNTL_H
31 #include <fcntl.h>
32 #endif
33 #ifdef HAVE_POSIX_SPAWN
34 #include <spawn.h>
35 #if !defined(__APPLE__)
36   extern char **environ;
37 #endif
38 #endif
39
40 namespace llvm {
41 using namespace sys;
42
43 Program::Program() : Data_(0) {}
44
45 Program::~Program() {}
46
47 unsigned Program::GetPid() const {
48   uint64_t pid = reinterpret_cast<uint64_t>(Data_);
49   return static_cast<unsigned>(pid);
50 }
51
52 // This function just uses the PATH environment variable to find the program.
53 Path
54 Program::FindProgramByName(const std::string& progName) {
55
56   // Check some degenerate cases
57   if (progName.length() == 0) // no program
58     return Path();
59   Path temp;
60   if (!temp.set(progName)) // invalid name
61     return Path();
62   // Use the given path verbatim if it contains any slashes; this matches
63   // the behavior of sh(1) and friends.
64   if (progName.find('/') != std::string::npos)
65     return temp;
66
67   // At this point, the file name does not contain slashes. Search for it
68   // through the directories specified in the PATH environment variable.
69
70   // Get the path. If its empty, we can't do anything to find it.
71   const char *PathStr = getenv("PATH");
72   if (PathStr == 0)
73     return Path();
74
75   // Now we have a colon separated list of directories to search; try them.
76   size_t PathLen = strlen(PathStr);
77   while (PathLen) {
78     // Find the first colon...
79     const char *Colon = std::find(PathStr, PathStr+PathLen, ':');
80
81     // Check to see if this first directory contains the executable...
82     Path FilePath;
83     if (FilePath.set(std::string(PathStr,Colon))) {
84       FilePath.appendComponent(progName);
85       if (FilePath.canExecute())
86         return FilePath;                    // Found the executable!
87     }
88
89     // Nope it wasn't in this directory, check the next path in the list!
90     PathLen -= Colon-PathStr;
91     PathStr = Colon;
92
93     // Advance past duplicate colons
94     while (*PathStr == ':') {
95       PathStr++;
96       PathLen--;
97     }
98   }
99   return Path();
100 }
101
102 static bool RedirectIO(const Path *Path, int FD, std::string* ErrMsg) {
103   if (Path == 0) // Noop
104     return false;
105   std::string File;
106   if (Path->isEmpty())
107     // Redirect empty paths to /dev/null
108     File = "/dev/null";
109   else
110     File = Path->str();
111
112   // Open the file
113   int InFD = open(File.c_str(), FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666);
114   if (InFD == -1) {
115     MakeErrMsg(ErrMsg, "Cannot open file '" + File + "' for "
116               + (FD == 0 ? "input" : "output"));
117     return true;
118   }
119
120   // Install it as the requested FD
121   if (dup2(InFD, FD) == -1) {
122     MakeErrMsg(ErrMsg, "Cannot dup2");
123     close(InFD);
124     return true;
125   }
126   close(InFD);      // Close the original FD
127   return false;
128 }
129
130 #ifdef HAVE_POSIX_SPAWN
131 static bool RedirectIO_PS(const Path *Path, int FD, std::string *ErrMsg,
132                           posix_spawn_file_actions_t &FileActions) {
133   if (Path == 0) // Noop
134     return false;
135   std::string File;
136   if (Path->isEmpty())
137     // Redirect empty paths to /dev/null
138     File = "/dev/null";
139   else
140     File = Path->str();
141     
142   if (int Err = posix_spawn_file_actions_addopen(&FileActions, FD,
143                     File.c_str(), 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   // Virtual memory.
170   getrlimit (RLIMIT_AS, &r);
171   r.rlim_cur = limit;
172   setrlimit (RLIMIT_AS, &r);
173 #endif
174 #endif
175 }
176
177 bool
178 Program::Execute(const Path &path, const char **args, const char **envp,
179                  const Path **redirects, unsigned memoryLimit,
180                   std::string *ErrMsg) {
181   // If this OS has posix_spawn and there is no memory limit being implied, use
182   // posix_spawn.  It is more efficient than fork/exec.
183 #ifdef HAVE_POSIX_SPAWN
184   if (memoryLimit == 0) {
185     posix_spawn_file_actions_t FileActions;
186     posix_spawn_file_actions_init(&FileActions);
187
188     if (redirects) {
189       // Redirect stdin/stdout.
190       if (RedirectIO_PS(redirects[0], 0, ErrMsg, FileActions) ||
191           RedirectIO_PS(redirects[1], 1, ErrMsg, FileActions))
192         return false;
193       if (redirects[1] == 0 || redirects[2] == 0 ||
194           *redirects[1] != *redirects[2]) {
195         // Just redirect stderr
196         if (RedirectIO_PS(redirects[2], 2, ErrMsg, FileActions)) return false;
197       } else {       
198         // If stdout and stderr should go to the same place, redirect stderr
199         // to the FD already open for stdout.
200         if (int Err = posix_spawn_file_actions_adddup2(&FileActions, 1, 2))
201           return !MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout", Err);
202       }
203     }
204
205 #if !defined(__APPLE__)
206     if (!envp) envp = (const char**)environ;
207 #endif
208
209     pid_t PID;
210     int Err = posix_spawn(&PID, path.c_str(), &FileActions,
211                           /*attrp*/0, (char**)args, (char**)envp);
212                           
213     posix_spawn_file_actions_destroy(&FileActions);
214
215     if (Err)
216      return !MakeErrMsg(ErrMsg, "posix_spawn failed", Err);
217       
218     Data_ = reinterpret_cast<void*>(PID);
219     return true;
220   }
221 #endif
222   
223   if (!path.canExecute()) {
224     if (ErrMsg)
225       *ErrMsg = path.str() + " is not executable";
226     return false;
227   }
228
229   // Create a child process.
230   int child = fork();
231   switch (child) {
232     // An error occured:  Return to the caller.
233     case -1:
234       MakeErrMsg(ErrMsg, "Couldn't fork");
235       return false;
236
237     // Child process: Execute the program.
238     case 0: {
239       // Redirect file descriptors...
240       if (redirects) {
241         // Redirect stdin
242         if (RedirectIO(redirects[0], 0, ErrMsg)) { return false; }
243         // Redirect stdout
244         if (RedirectIO(redirects[1], 1, ErrMsg)) { return false; }
245         if (redirects[1] && redirects[2] &&
246             *(redirects[1]) == *(redirects[2])) {
247           // If stdout and stderr should go to the same place, redirect stderr
248           // to the FD already open for stdout.
249           if (-1 == dup2(1,2)) {
250             MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout");
251             return false;
252           }
253         } else {
254           // Just redirect stderr
255           if (RedirectIO(redirects[2], 2, ErrMsg)) { return false; }
256         }
257       }
258
259       // Set memory limits
260       if (memoryLimit!=0) {
261         SetMemoryLimits(memoryLimit);
262       }
263
264       // Execute!
265       if (envp != 0)
266         execve(path.c_str(), (char**)args, (char**)envp);
267       else
268         execv(path.c_str(), (char**)args);
269       // If the execve() failed, we should exit. Follow Unix protocol and
270       // return 127 if the executable was not found, and 126 otherwise.
271       // Use _exit rather than exit so that atexit functions and static
272       // object destructors cloned from the parent process aren't
273       // redundantly run, and so that any data buffered in stdio buffers
274       // cloned from the parent aren't redundantly written out.
275       _exit(errno == ENOENT ? 127 : 126);
276     }
277
278     // Parent process: Break out of the switch to do our processing.
279     default:
280       break;
281   }
282
283   Data_ = reinterpret_cast<void*>(child);
284
285   return true;
286 }
287
288 int
289 Program::Wait(unsigned secondsToWait,
290               std::string* ErrMsg)
291 {
292 #ifdef HAVE_SYS_WAIT_H
293   struct sigaction Act, Old;
294
295   if (Data_ == 0) {
296     MakeErrMsg(ErrMsg, "Process not started!");
297     return -1;
298   }
299
300   // Install a timeout handler.  The handler itself does nothing, but the simple
301   // fact of having a handler at all causes the wait below to return with EINTR,
302   // unlike if we used SIG_IGN.
303   if (secondsToWait) {
304 #ifndef __HAIKU__
305     Act.sa_sigaction = 0;
306 #endif
307     Act.sa_handler = TimeOutHandler;
308     sigemptyset(&Act.sa_mask);
309     Act.sa_flags = 0;
310     sigaction(SIGALRM, &Act, &Old);
311     alarm(secondsToWait);
312   }
313
314   // Parent process: Wait for the child process to terminate.
315   int status;
316   uint64_t pid = reinterpret_cast<uint64_t>(Data_);
317   pid_t child = static_cast<pid_t>(pid);
318   while (waitpid(pid, &status, 0) != child)
319     if (secondsToWait && errno == EINTR) {
320       // Kill the child.
321       kill(child, SIGKILL);
322
323       // Turn off the alarm and restore the signal handler
324       alarm(0);
325       sigaction(SIGALRM, &Old, 0);
326
327       // Wait for child to die
328       if (wait(&status) != child)
329         MakeErrMsg(ErrMsg, "Child timed out but wouldn't die");
330       else
331         MakeErrMsg(ErrMsg, "Child timed out", 0);
332
333       return -1;   // Timeout detected
334     } else if (errno != EINTR) {
335       MakeErrMsg(ErrMsg, "Error waiting for child process");
336       return -1;
337     }
338
339   // We exited normally without timeout, so turn off the timer.
340   if (secondsToWait) {
341     alarm(0);
342     sigaction(SIGALRM, &Old, 0);
343   }
344
345   // Return the proper exit status. 0=success, >0 is programs' exit status,
346   // <0 means a signal was returned, -9999999 means the program dumped core.
347   int result = 0;
348   if (WIFEXITED(status))
349     result = WEXITSTATUS(status);
350   else if (WIFSIGNALED(status))
351     result = 0 - WTERMSIG(status);
352 #ifdef WCOREDUMP
353   else if (WCOREDUMP(status))
354     result |= 0x01000000;
355 #endif
356   return result;
357 #else
358   return -99;
359 #endif
360
361 }
362
363 bool
364 Program::Kill(std::string* ErrMsg) {
365   if (Data_ == 0) {
366     MakeErrMsg(ErrMsg, "Process not started!");
367     return true;
368   }
369
370   uint64_t pid64 = reinterpret_cast<uint64_t>(Data_);
371   pid_t pid = static_cast<pid_t>(pid64);
372
373   if (kill(pid, SIGKILL) != 0) {
374     MakeErrMsg(ErrMsg, "The process couldn't be killed!");
375     return true;
376   }
377
378   return false;
379 }
380
381 bool Program::ChangeStdinToBinary(){
382   // Do nothing, as Unix doesn't differentiate between text and binary.
383   return false;
384 }
385
386 bool Program::ChangeStdoutToBinary(){
387   // Do nothing, as Unix doesn't differentiate between text and binary.
388   return false;
389 }
390
391 bool Program::ChangeStderrToBinary(){
392   // Do nothing, as Unix doesn't differentiate between text and binary.
393   return false;
394 }
395
396 }