1//===- llvm/Support/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 "Unix.h" 20#include "llvm/Support/Compiler.h" 21#include "llvm/Support/FileSystem.h" 22#include <llvm/Config/config.h> 23#if HAVE_SYS_STAT_H 24#include <sys/stat.h> 25#endif 26#if HAVE_SYS_RESOURCE_H 27#include <sys/resource.h> 28#endif 29#if HAVE_SIGNAL_H 30#include <signal.h> 31#endif 32#if HAVE_FCNTL_H 33#include <fcntl.h> 34#endif 35#if HAVE_UNISTD_H 36#include <unistd.h> 37#endif 38#ifdef HAVE_POSIX_SPAWN 39#include <spawn.h> 40#if !defined(__APPLE__) 41 extern char **environ; 42#else 43#include <crt_externs.h> // _NSGetEnviron 44#endif 45#endif 46 47namespace llvm { 48using namespace sys; 49 50Program::Program() : Data_(0) {} 51 52Program::~Program() {} 53 54// This function just uses the PATH environment variable to find the program. 55Path 56Program::FindProgramByName(const std::string& progName) { 57 58 // Check some degenerate cases 59 if (progName.length() == 0) // no program 60 return Path(); 61 Path temp; 62 if (!temp.set(progName)) // invalid name 63 return Path(); 64 // Use the given path verbatim if it contains any slashes; this matches 65 // the behavior of sh(1) and friends. 66 if (progName.find('/') != std::string::npos) 67 return temp; 68 69 // At this point, the file name is valid and does not contain slashes. Search 70 // for it through the directories specified in the PATH environment variable. 71 72 // Get the path. If its empty, we can't do anything to find it. 73 const char *PathStr = getenv("PATH"); 74 if (PathStr == 0) 75 return Path(); 76 77 // Now we have a colon separated list of directories to search; try them. 78 size_t PathLen = strlen(PathStr); 79 while (PathLen) { 80 // Find the first colon... 81 const char *Colon = std::find(PathStr, PathStr+PathLen, ':'); 82 83 // Check to see if this first directory contains the executable... 84 Path FilePath; 85 if (FilePath.set(std::string(PathStr,Colon))) { 86 FilePath.appendComponent(progName); 87 if (FilePath.canExecute()) 88 return FilePath; // Found the executable! 89 } 90 91 // Nope it wasn't in this directory, check the next path in the list! 92 PathLen -= Colon-PathStr; 93 PathStr = Colon; 94 95 // Advance past duplicate colons 96 while (*PathStr == ':') { 97 PathStr++; 98 PathLen--; 99 } 100 } 101 return Path(); 102} 103 104static bool RedirectIO(const Path *Path, int FD, std::string* ErrMsg) { 105 if (Path == 0) // Noop 106 return false; 107 const char *File; 108 if (Path->isEmpty()) 109 // Redirect empty paths to /dev/null 110 File = "/dev/null"; 111 else 112 File = Path->c_str(); 113 114 // Open the file 115 int InFD = open(File, FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666); 116 if (InFD == -1) { 117 MakeErrMsg(ErrMsg, "Cannot open file '" + std::string(File) + "' for " 118 + (FD == 0 ? "input" : "output")); 119 return true; 120 } 121 122 // Install it as the requested FD 123 if (dup2(InFD, FD) == -1) { 124 MakeErrMsg(ErrMsg, "Cannot dup2"); 125 close(InFD); 126 return true; 127 } 128 close(InFD); // Close the original FD 129 return false; 130} 131 132#ifdef HAVE_POSIX_SPAWN 133static bool RedirectIO_PS(const Path *Path, int FD, std::string *ErrMsg, 134 posix_spawn_file_actions_t *FileActions) { 135 if (Path == 0) // Noop 136 return false; 137 const char *File; 138 if (Path->isEmpty()) 139 // Redirect empty paths to /dev/null 140 File = "/dev/null"; 141 else 142 File = Path->c_str(); 143 144 if (int Err = posix_spawn_file_actions_addopen(FileActions, FD, 145 File, FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666)) 146 return MakeErrMsg(ErrMsg, "Cannot dup2", Err); 147 return false; 148} 149#endif 150 151static void TimeOutHandler(int Sig) { 152} 153 154static void SetMemoryLimits (unsigned size) 155{ 156#if HAVE_SYS_RESOURCE_H && HAVE_GETRLIMIT && HAVE_SETRLIMIT 157 struct rlimit r; 158 __typeof__ (r.rlim_cur) limit = (__typeof__ (r.rlim_cur)) (size) * 1048576; 159 160 // Heap size 161 getrlimit (RLIMIT_DATA, &r); 162 r.rlim_cur = limit; 163 setrlimit (RLIMIT_DATA, &r); 164#ifdef RLIMIT_RSS 165 // Resident set size. 166 getrlimit (RLIMIT_RSS, &r); 167 r.rlim_cur = limit; 168 setrlimit (RLIMIT_RSS, &r); 169#endif 170#ifdef RLIMIT_AS // e.g. NetBSD doesn't have it. 171 // Don't set virtual memory limit if built with any Sanitizer. They need 80Tb 172 // of virtual memory for shadow memory mapping. 173#if !LLVM_MEMORY_SANITIZER_BUILD && !LLVM_ADDRESS_SANITIZER_BUILD 174 // Virtual memory. 175 getrlimit (RLIMIT_AS, &r); 176 r.rlim_cur = limit; 177 setrlimit (RLIMIT_AS, &r); 178#endif 179#endif 180#endif 181} 182 183bool 184Program::Execute(const Path &path, const char **args, const char **envp, 185 const Path **redirects, unsigned memoryLimit, 186 std::string *ErrMsg) { 187 // If this OS has posix_spawn and there is no memory limit being implied, use 188 // posix_spawn. It is more efficient than fork/exec. 189#ifdef HAVE_POSIX_SPAWN 190 if (memoryLimit == 0) { 191 posix_spawn_file_actions_t FileActionsStore; 192 posix_spawn_file_actions_t *FileActions = 0; 193 194 if (redirects) { 195 FileActions = &FileActionsStore; 196 posix_spawn_file_actions_init(FileActions); 197 198 // Redirect stdin/stdout. 199 if (RedirectIO_PS(redirects[0], 0, ErrMsg, FileActions) || 200 RedirectIO_PS(redirects[1], 1, ErrMsg, FileActions)) 201 return false; 202 if (redirects[1] == 0 || redirects[2] == 0 || 203 *redirects[1] != *redirects[2]) { 204 // Just redirect stderr 205 if (RedirectIO_PS(redirects[2], 2, ErrMsg, FileActions)) return false; 206 } else { 207 // If stdout and stderr should go to the same place, redirect stderr 208 // to the FD already open for stdout. 209 if (int Err = posix_spawn_file_actions_adddup2(FileActions, 1, 2)) 210 return !MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout", Err); 211 } 212 } 213 214 if (!envp) 215#if !defined(__APPLE__) 216 envp = const_cast<const char **>(environ); 217#else 218 // environ is missing in dylibs. 219 envp = const_cast<const char **>(*_NSGetEnviron()); 220#endif 221 222 // Explicitly initialized to prevent what appears to be a valgrind false 223 // positive. 224 pid_t PID = 0; 225 int Err = posix_spawn(&PID, path.c_str(), FileActions, /*attrp*/0, 226 const_cast<char **>(args), const_cast<char **>(envp)); 227 228 if (FileActions) 229 posix_spawn_file_actions_destroy(FileActions); 230 231 if (Err) 232 return !MakeErrMsg(ErrMsg, "posix_spawn failed", Err); 233 234 Data_ = reinterpret_cast<void*>(PID); 235 return true; 236 } 237#endif 238 239 // Create a child process. 240 int child = fork(); 241 switch (child) { 242 // An error occurred: Return to the caller. 243 case -1: 244 MakeErrMsg(ErrMsg, "Couldn't fork"); 245 return false; 246 247 // Child process: Execute the program. 248 case 0: { 249 // Redirect file descriptors... 250 if (redirects) { 251 // Redirect stdin 252 if (RedirectIO(redirects[0], 0, ErrMsg)) { return false; } 253 // Redirect stdout 254 if (RedirectIO(redirects[1], 1, ErrMsg)) { return false; } 255 if (redirects[1] && redirects[2] && 256 *(redirects[1]) == *(redirects[2])) { 257 // If stdout and stderr should go to the same place, redirect stderr 258 // to the FD already open for stdout. 259 if (-1 == dup2(1,2)) { 260 MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout"); 261 return false; 262 } 263 } else { 264 // Just redirect stderr 265 if (RedirectIO(redirects[2], 2, ErrMsg)) { return false; } 266 } 267 } 268 269 // Set memory limits 270 if (memoryLimit!=0) { 271 SetMemoryLimits(memoryLimit); 272 } 273 274 // Execute! 275 if (envp != 0) 276 execve(path.c_str(), 277 const_cast<char **>(args), 278 const_cast<char **>(envp)); 279 else 280 execv(path.c_str(), 281 const_cast<char **>(args)); 282 // If the execve() failed, we should exit. Follow Unix protocol and 283 // return 127 if the executable was not found, and 126 otherwise. 284 // Use _exit rather than exit so that atexit functions and static 285 // object destructors cloned from the parent process aren't 286 // redundantly run, and so that any data buffered in stdio buffers 287 // cloned from the parent aren't redundantly written out. 288 _exit(errno == ENOENT ? 127 : 126); 289 } 290 291 // Parent process: Break out of the switch to do our processing. 292 default: 293 break; 294 } 295 296 Data_ = reinterpret_cast<void*>(child); 297 298 return true; 299} 300 301int 302Program::Wait(const sys::Path &path, 303 unsigned secondsToWait, 304 std::string* ErrMsg) 305{ 306#ifdef HAVE_SYS_WAIT_H 307 struct sigaction Act, Old; 308 309 if (Data_ == 0) { 310 MakeErrMsg(ErrMsg, "Process not started!"); 311 return -1; 312 } 313 314 // Install a timeout handler. The handler itself does nothing, but the simple 315 // fact of having a handler at all causes the wait below to return with EINTR, 316 // unlike if we used SIG_IGN. 317 if (secondsToWait) { 318 memset(&Act, 0, sizeof(Act)); 319 Act.sa_handler = TimeOutHandler; 320 sigemptyset(&Act.sa_mask); 321 sigaction(SIGALRM, &Act, &Old); 322 alarm(secondsToWait); 323 } 324 325 // Parent process: Wait for the child process to terminate. 326 int status; 327 uint64_t pid = reinterpret_cast<uint64_t>(Data_); 328 pid_t child = static_cast<pid_t>(pid); 329 while (waitpid(pid, &status, 0) != child) 330 if (secondsToWait && errno == EINTR) { 331 // Kill the child. 332 kill(child, SIGKILL); 333 334 // Turn off the alarm and restore the signal handler 335 alarm(0); 336 sigaction(SIGALRM, &Old, 0); 337 338 // Wait for child to die 339 if (wait(&status) != child) 340 MakeErrMsg(ErrMsg, "Child timed out but wouldn't die"); 341 else 342 MakeErrMsg(ErrMsg, "Child timed out", 0); 343 344 return -2; // Timeout detected 345 } else if (errno != EINTR) { 346 MakeErrMsg(ErrMsg, "Error waiting for child process"); 347 return -1; 348 } 349 350 // We exited normally without timeout, so turn off the timer. 351 if (secondsToWait) { 352 alarm(0); 353 sigaction(SIGALRM, &Old, 0); 354 } 355 356 // Return the proper exit status. Detect error conditions 357 // so we can return -1 for them and set ErrMsg informatively. 358 int result = 0; 359 if (WIFEXITED(status)) { 360 result = WEXITSTATUS(status); 361#ifdef HAVE_POSIX_SPAWN 362 // The posix_spawn child process returns 127 on any kind of error. 363 // Following the POSIX convention for command-line tools (which posix_spawn 364 // itself apparently does not), check to see if the failure was due to some 365 // reason other than the file not existing, and return 126 in this case. 366 bool Exists; 367 if (result == 127 && !llvm::sys::fs::exists(path.str(), Exists) && Exists) 368 result = 126; 369#endif 370 if (result == 127) { 371 if (ErrMsg) 372 *ErrMsg = llvm::sys::StrError(ENOENT); 373 return -1; 374 } 375 if (result == 126) { 376 if (ErrMsg) 377 *ErrMsg = "Program could not be executed"; 378 return -1; 379 } 380 } else if (WIFSIGNALED(status)) { 381 if (ErrMsg) { 382 *ErrMsg = strsignal(WTERMSIG(status)); 383#ifdef WCOREDUMP 384 if (WCOREDUMP(status)) 385 *ErrMsg += " (core dumped)"; 386#endif 387 } 388 // Return a special value to indicate that the process received an unhandled 389 // signal during execution as opposed to failing to execute. 390 return -2; 391 } 392 return result; 393#else 394 if (ErrMsg) 395 *ErrMsg = "Program::Wait is not implemented on this platform yet!"; 396 return -1; 397#endif 398} 399 400error_code Program::ChangeStdinToBinary(){ 401 // Do nothing, as Unix doesn't differentiate between text and binary. 402 return make_error_code(errc::success); 403} 404 405error_code Program::ChangeStdoutToBinary(){ 406 // Do nothing, as Unix doesn't differentiate between text and binary. 407 return make_error_code(errc::success); 408} 409 410error_code Program::ChangeStderrToBinary(){ 411 // Do nothing, as Unix doesn't differentiate between text and binary. 412 return make_error_code(errc::success); 413} 414 415bool llvm::sys::argumentsFitWithinSystemLimits(ArrayRef<const char*> Args) { 416 static long ArgMax = sysconf(_SC_ARG_MAX); 417 418 // System says no practical limit. 419 if (ArgMax == -1) 420 return true; 421 422 // Conservatively account for space required by environment variables. 423 ArgMax /= 2; 424 425 size_t ArgLength = 0; 426 for (ArrayRef<const char*>::iterator I = Args.begin(), E = Args.end(); 427 I != E; ++I) { 428 ArgLength += strlen(*I) + 1; 429 if (ArgLength > size_t(ArgMax)) { 430 return false; 431 } 432 } 433 return true; 434} 435 436} 437