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