LLVM API Documentation
00001 //===- llvm/Support/Unix/Program.cpp -----------------------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the Unix specific portion of the Program class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 //===----------------------------------------------------------------------===// 00015 //=== WARNING: Implementation here must contain only generic UNIX code that 00016 //=== is guaranteed to work on *all* UNIX variants. 00017 //===----------------------------------------------------------------------===// 00018 00019 #include "Unix.h" 00020 #include "llvm/Support/Compiler.h" 00021 #include "llvm/Support/FileSystem.h" 00022 #include "llvm/Support/raw_ostream.h" 00023 #include <llvm/Config/config.h> 00024 #if HAVE_SYS_STAT_H 00025 #include <sys/stat.h> 00026 #endif 00027 #if HAVE_SYS_RESOURCE_H 00028 #include <sys/resource.h> 00029 #endif 00030 #if HAVE_SIGNAL_H 00031 #include <signal.h> 00032 #endif 00033 #if HAVE_FCNTL_H 00034 #include <fcntl.h> 00035 #endif 00036 #if HAVE_UNISTD_H 00037 #include <unistd.h> 00038 #endif 00039 #ifdef HAVE_POSIX_SPAWN 00040 #ifdef __sun__ 00041 #define _RESTRICT_KYWD 00042 #endif 00043 #include <spawn.h> 00044 #if !defined(__APPLE__) 00045 extern char **environ; 00046 #else 00047 #include <crt_externs.h> // _NSGetEnviron 00048 #endif 00049 #endif 00050 00051 namespace llvm { 00052 00053 using namespace sys; 00054 00055 ProcessInfo::ProcessInfo() : Pid(0), ReturnCode(0) {} 00056 00057 // This function just uses the PATH environment variable to find the program. 00058 std::string 00059 sys::FindProgramByName(const std::string& progName) { 00060 00061 // Check some degenerate cases 00062 if (progName.length() == 0) // no program 00063 return ""; 00064 std::string temp = progName; 00065 // Use the given path verbatim if it contains any slashes; this matches 00066 // the behavior of sh(1) and friends. 00067 if (progName.find('/') != std::string::npos) 00068 return temp; 00069 00070 // At this point, the file name is valid and does not contain slashes. Search 00071 // for it through the directories specified in the PATH environment variable. 00072 00073 // Get the path. If its empty, we can't do anything to find it. 00074 const char *PathStr = getenv("PATH"); 00075 if (!PathStr) 00076 return ""; 00077 00078 // Now we have a colon separated list of directories to search; try them. 00079 size_t PathLen = strlen(PathStr); 00080 while (PathLen) { 00081 // Find the first colon... 00082 const char *Colon = std::find(PathStr, PathStr+PathLen, ':'); 00083 00084 // Check to see if this first directory contains the executable... 00085 SmallString<128> FilePath(PathStr,Colon); 00086 sys::path::append(FilePath, progName); 00087 if (sys::fs::can_execute(Twine(FilePath))) 00088 return FilePath.str(); // Found the executable! 00089 00090 // Nope it wasn't in this directory, check the next path in the list! 00091 PathLen -= Colon-PathStr; 00092 PathStr = Colon; 00093 00094 // Advance past duplicate colons 00095 while (*PathStr == ':') { 00096 PathStr++; 00097 PathLen--; 00098 } 00099 } 00100 return ""; 00101 } 00102 00103 static bool RedirectIO(const StringRef *Path, int FD, std::string* ErrMsg) { 00104 if (!Path) // Noop 00105 return false; 00106 std::string File; 00107 if (Path->empty()) 00108 // Redirect empty paths to /dev/null 00109 File = "/dev/null"; 00110 else 00111 File = *Path; 00112 00113 // Open the file 00114 int InFD = open(File.c_str(), FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666); 00115 if (InFD == -1) { 00116 MakeErrMsg(ErrMsg, "Cannot open file '" + File + "' for " 00117 + (FD == 0 ? "input" : "output")); 00118 return true; 00119 } 00120 00121 // Install it as the requested FD 00122 if (dup2(InFD, FD) == -1) { 00123 MakeErrMsg(ErrMsg, "Cannot dup2"); 00124 close(InFD); 00125 return true; 00126 } 00127 close(InFD); // Close the original FD 00128 return false; 00129 } 00130 00131 #ifdef HAVE_POSIX_SPAWN 00132 static bool RedirectIO_PS(const std::string *Path, int FD, std::string *ErrMsg, 00133 posix_spawn_file_actions_t *FileActions) { 00134 if (!Path) // Noop 00135 return false; 00136 const char *File; 00137 if (Path->empty()) 00138 // Redirect empty paths to /dev/null 00139 File = "/dev/null"; 00140 else 00141 File = Path->c_str(); 00142 00143 if (int Err = posix_spawn_file_actions_addopen( 00144 FileActions, FD, File, 00145 FD == 0 ? O_RDONLY : O_WRONLY | O_CREAT, 0666)) 00146 return MakeErrMsg(ErrMsg, "Cannot dup2", Err); 00147 return false; 00148 } 00149 #endif 00150 00151 static void TimeOutHandler(int Sig) { 00152 } 00153 00154 static void SetMemoryLimits (unsigned size) 00155 { 00156 #if HAVE_SYS_RESOURCE_H && HAVE_GETRLIMIT && HAVE_SETRLIMIT 00157 struct rlimit r; 00158 __typeof__ (r.rlim_cur) limit = (__typeof__ (r.rlim_cur)) (size) * 1048576; 00159 00160 // Heap size 00161 getrlimit (RLIMIT_DATA, &r); 00162 r.rlim_cur = limit; 00163 setrlimit (RLIMIT_DATA, &r); 00164 #ifdef RLIMIT_RSS 00165 // Resident set size. 00166 getrlimit (RLIMIT_RSS, &r); 00167 r.rlim_cur = limit; 00168 setrlimit (RLIMIT_RSS, &r); 00169 #endif 00170 #ifdef RLIMIT_AS // e.g. NetBSD doesn't have it. 00171 // Don't set virtual memory limit if built with any Sanitizer. They need 80Tb 00172 // of virtual memory for shadow memory mapping. 00173 #if !LLVM_MEMORY_SANITIZER_BUILD && !LLVM_ADDRESS_SANITIZER_BUILD 00174 // Virtual memory. 00175 getrlimit (RLIMIT_AS, &r); 00176 r.rlim_cur = limit; 00177 setrlimit (RLIMIT_AS, &r); 00178 #endif 00179 #endif 00180 #endif 00181 } 00182 00183 } 00184 00185 static bool Execute(ProcessInfo &PI, StringRef Program, const char **args, 00186 const char **envp, const StringRef **redirects, 00187 unsigned memoryLimit, std::string *ErrMsg) { 00188 if (!llvm::sys::fs::exists(Program)) { 00189 if (ErrMsg) 00190 *ErrMsg = std::string("Executable \"") + Program.str() + 00191 std::string("\" doesn't exist!"); 00192 return false; 00193 } 00194 00195 // If this OS has posix_spawn and there is no memory limit being implied, use 00196 // posix_spawn. It is more efficient than fork/exec. 00197 #ifdef HAVE_POSIX_SPAWN 00198 if (memoryLimit == 0) { 00199 posix_spawn_file_actions_t FileActionsStore; 00200 posix_spawn_file_actions_t *FileActions = nullptr; 00201 00202 // If we call posix_spawn_file_actions_addopen we have to make sure the 00203 // c strings we pass to it stay alive until the call to posix_spawn, 00204 // so we copy any StringRefs into this variable. 00205 std::string RedirectsStorage[3]; 00206 00207 if (redirects) { 00208 std::string *RedirectsStr[3] = {nullptr, nullptr, nullptr}; 00209 for (int I = 0; I < 3; ++I) { 00210 if (redirects[I]) { 00211 RedirectsStorage[I] = *redirects[I]; 00212 RedirectsStr[I] = &RedirectsStorage[I]; 00213 } 00214 } 00215 00216 FileActions = &FileActionsStore; 00217 posix_spawn_file_actions_init(FileActions); 00218 00219 // Redirect stdin/stdout. 00220 if (RedirectIO_PS(RedirectsStr[0], 0, ErrMsg, FileActions) || 00221 RedirectIO_PS(RedirectsStr[1], 1, ErrMsg, FileActions)) 00222 return false; 00223 if (redirects[1] == nullptr || redirects[2] == nullptr || 00224 *redirects[1] != *redirects[2]) { 00225 // Just redirect stderr 00226 if (RedirectIO_PS(RedirectsStr[2], 2, ErrMsg, FileActions)) 00227 return false; 00228 } else { 00229 // If stdout and stderr should go to the same place, redirect stderr 00230 // to the FD already open for stdout. 00231 if (int Err = posix_spawn_file_actions_adddup2(FileActions, 1, 2)) 00232 return !MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout", Err); 00233 } 00234 } 00235 00236 if (!envp) 00237 #if !defined(__APPLE__) 00238 envp = const_cast<const char **>(environ); 00239 #else 00240 // environ is missing in dylibs. 00241 envp = const_cast<const char **>(*_NSGetEnviron()); 00242 #endif 00243 00244 // Explicitly initialized to prevent what appears to be a valgrind false 00245 // positive. 00246 pid_t PID = 0; 00247 int Err = posix_spawn(&PID, Program.str().c_str(), FileActions, 00248 /*attrp*/nullptr, const_cast<char **>(args), 00249 const_cast<char **>(envp)); 00250 00251 if (FileActions) 00252 posix_spawn_file_actions_destroy(FileActions); 00253 00254 if (Err) 00255 return !MakeErrMsg(ErrMsg, "posix_spawn failed", Err); 00256 00257 PI.Pid = PID; 00258 00259 return true; 00260 } 00261 #endif 00262 00263 // Create a child process. 00264 int child = fork(); 00265 switch (child) { 00266 // An error occurred: Return to the caller. 00267 case -1: 00268 MakeErrMsg(ErrMsg, "Couldn't fork"); 00269 return false; 00270 00271 // Child process: Execute the program. 00272 case 0: { 00273 // Redirect file descriptors... 00274 if (redirects) { 00275 // Redirect stdin 00276 if (RedirectIO(redirects[0], 0, ErrMsg)) { return false; } 00277 // Redirect stdout 00278 if (RedirectIO(redirects[1], 1, ErrMsg)) { return false; } 00279 if (redirects[1] && redirects[2] && 00280 *(redirects[1]) == *(redirects[2])) { 00281 // If stdout and stderr should go to the same place, redirect stderr 00282 // to the FD already open for stdout. 00283 if (-1 == dup2(1,2)) { 00284 MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout"); 00285 return false; 00286 } 00287 } else { 00288 // Just redirect stderr 00289 if (RedirectIO(redirects[2], 2, ErrMsg)) { return false; } 00290 } 00291 } 00292 00293 // Set memory limits 00294 if (memoryLimit!=0) { 00295 SetMemoryLimits(memoryLimit); 00296 } 00297 00298 // Execute! 00299 std::string PathStr = Program; 00300 if (envp != nullptr) 00301 execve(PathStr.c_str(), 00302 const_cast<char **>(args), 00303 const_cast<char **>(envp)); 00304 else 00305 execv(PathStr.c_str(), 00306 const_cast<char **>(args)); 00307 // If the execve() failed, we should exit. Follow Unix protocol and 00308 // return 127 if the executable was not found, and 126 otherwise. 00309 // Use _exit rather than exit so that atexit functions and static 00310 // object destructors cloned from the parent process aren't 00311 // redundantly run, and so that any data buffered in stdio buffers 00312 // cloned from the parent aren't redundantly written out. 00313 _exit(errno == ENOENT ? 127 : 126); 00314 } 00315 00316 // Parent process: Break out of the switch to do our processing. 00317 default: 00318 break; 00319 } 00320 00321 PI.Pid = child; 00322 00323 return true; 00324 } 00325 00326 namespace llvm { 00327 00328 ProcessInfo sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait, 00329 bool WaitUntilTerminates, std::string *ErrMsg) { 00330 #ifdef HAVE_SYS_WAIT_H 00331 struct sigaction Act, Old; 00332 assert(PI.Pid && "invalid pid to wait on, process not started?"); 00333 00334 int WaitPidOptions = 0; 00335 pid_t ChildPid = PI.Pid; 00336 if (WaitUntilTerminates) { 00337 SecondsToWait = 0; 00338 ChildPid = -1; // mimic a wait() using waitpid() 00339 } else if (SecondsToWait) { 00340 // Install a timeout handler. The handler itself does nothing, but the 00341 // simple fact of having a handler at all causes the wait below to return 00342 // with EINTR, unlike if we used SIG_IGN. 00343 memset(&Act, 0, sizeof(Act)); 00344 Act.sa_handler = TimeOutHandler; 00345 sigemptyset(&Act.sa_mask); 00346 sigaction(SIGALRM, &Act, &Old); 00347 alarm(SecondsToWait); 00348 } else if (SecondsToWait == 0) 00349 WaitPidOptions = WNOHANG; 00350 00351 // Parent process: Wait for the child process to terminate. 00352 int status; 00353 ProcessInfo WaitResult; 00354 00355 do { 00356 WaitResult.Pid = waitpid(ChildPid, &status, WaitPidOptions); 00357 } while (WaitUntilTerminates && WaitResult.Pid == -1 && errno == EINTR); 00358 00359 if (WaitResult.Pid != PI.Pid) { 00360 if (WaitResult.Pid == 0) { 00361 // Non-blocking wait. 00362 return WaitResult; 00363 } else { 00364 if (SecondsToWait && errno == EINTR) { 00365 // Kill the child. 00366 kill(PI.Pid, SIGKILL); 00367 00368 // Turn off the alarm and restore the signal handler 00369 alarm(0); 00370 sigaction(SIGALRM, &Old, nullptr); 00371 00372 // Wait for child to die 00373 if (wait(&status) != ChildPid) 00374 MakeErrMsg(ErrMsg, "Child timed out but wouldn't die"); 00375 else 00376 MakeErrMsg(ErrMsg, "Child timed out", 0); 00377 00378 WaitResult.ReturnCode = -2; // Timeout detected 00379 return WaitResult; 00380 } else if (errno != EINTR) { 00381 MakeErrMsg(ErrMsg, "Error waiting for child process"); 00382 WaitResult.ReturnCode = -1; 00383 return WaitResult; 00384 } 00385 } 00386 } 00387 00388 // We exited normally without timeout, so turn off the timer. 00389 if (SecondsToWait && !WaitUntilTerminates) { 00390 alarm(0); 00391 sigaction(SIGALRM, &Old, nullptr); 00392 } 00393 00394 // Return the proper exit status. Detect error conditions 00395 // so we can return -1 for them and set ErrMsg informatively. 00396 int result = 0; 00397 if (WIFEXITED(status)) { 00398 result = WEXITSTATUS(status); 00399 WaitResult.ReturnCode = result; 00400 00401 if (result == 127) { 00402 if (ErrMsg) 00403 *ErrMsg = llvm::sys::StrError(ENOENT); 00404 WaitResult.ReturnCode = -1; 00405 return WaitResult; 00406 } 00407 if (result == 126) { 00408 if (ErrMsg) 00409 *ErrMsg = "Program could not be executed"; 00410 WaitResult.ReturnCode = -1; 00411 return WaitResult; 00412 } 00413 } else if (WIFSIGNALED(status)) { 00414 if (ErrMsg) { 00415 *ErrMsg = strsignal(WTERMSIG(status)); 00416 #ifdef WCOREDUMP 00417 if (WCOREDUMP(status)) 00418 *ErrMsg += " (core dumped)"; 00419 #endif 00420 } 00421 // Return a special value to indicate that the process received an unhandled 00422 // signal during execution as opposed to failing to execute. 00423 WaitResult.ReturnCode = -2; 00424 } 00425 #else 00426 if (ErrMsg) 00427 *ErrMsg = "Program::Wait is not implemented on this platform yet!"; 00428 ProcessInfo WaitResult; 00429 WaitResult.ReturnCode = -2; 00430 #endif 00431 return WaitResult; 00432 } 00433 00434 std::error_code sys::ChangeStdinToBinary(){ 00435 // Do nothing, as Unix doesn't differentiate between text and binary. 00436 return std::error_code(); 00437 } 00438 00439 std::error_code sys::ChangeStdoutToBinary(){ 00440 // Do nothing, as Unix doesn't differentiate between text and binary. 00441 return std::error_code(); 00442 } 00443 00444 std::error_code 00445 llvm::sys::writeFileWithEncoding(StringRef FileName, StringRef Contents, 00446 WindowsEncodingMethod Encoding /*unused*/) { 00447 std::error_code EC; 00448 llvm::raw_fd_ostream OS(FileName, EC, llvm::sys::fs::OpenFlags::F_Text); 00449 00450 if (EC) 00451 return EC; 00452 00453 OS << Contents; 00454 00455 if (OS.has_error()) 00456 return std::make_error_code(std::errc::io_error); 00457 00458 return EC; 00459 } 00460 00461 bool llvm::sys::argumentsFitWithinSystemLimits(ArrayRef<const char*> Args) { 00462 static long ArgMax = sysconf(_SC_ARG_MAX); 00463 00464 // System says no practical limit. 00465 if (ArgMax == -1) 00466 return true; 00467 00468 // Conservatively account for space required by environment variables. 00469 long HalfArgMax = ArgMax / 2; 00470 00471 size_t ArgLength = 0; 00472 for (ArrayRef<const char*>::iterator I = Args.begin(), E = Args.end(); 00473 I != E; ++I) { 00474 ArgLength += strlen(*I) + 1; 00475 if (ArgLength > size_t(HalfArgMax)) { 00476 return false; 00477 } 00478 } 00479 return true; 00480 } 00481 }