1 //===-- Program.cpp - Implement OS Program Concept --------------*- 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 operating system Program concept.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/Support/Program.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/Config/llvm-config.h"
17 #include <system_error>
18 using namespace llvm;
19 using namespace sys;
20
21 //===----------------------------------------------------------------------===//
22 //=== WARNING: Implementation here must contain only TRULY operating system
23 //=== independent code.
24 //===----------------------------------------------------------------------===//
25
26 static bool Execute(ProcessInfo &PI, StringRef Program,
27 ArrayRef<StringRef> Args, Optional<ArrayRef<StringRef>> Env,
28 ArrayRef<Optional<StringRef>> Redirects,
29 unsigned MemoryLimit, std::string *ErrMsg);
30
ExecuteAndWait(StringRef Program,ArrayRef<StringRef> Args,Optional<ArrayRef<StringRef>> Env,ArrayRef<Optional<StringRef>> Redirects,unsigned SecondsToWait,unsigned MemoryLimit,std::string * ErrMsg,bool * ExecutionFailed)31 int sys::ExecuteAndWait(StringRef Program, ArrayRef<StringRef> Args,
32 Optional<ArrayRef<StringRef>> Env,
33 ArrayRef<Optional<StringRef>> Redirects,
34 unsigned SecondsToWait, unsigned MemoryLimit,
35 std::string *ErrMsg, bool *ExecutionFailed) {
36 assert(Redirects.empty() || Redirects.size() == 3);
37 ProcessInfo PI;
38 if (Execute(PI, Program, Args, Env, Redirects, MemoryLimit, ErrMsg)) {
39 if (ExecutionFailed)
40 *ExecutionFailed = false;
41 ProcessInfo Result = Wait(
42 PI, SecondsToWait, /*WaitUntilTerminates=*/SecondsToWait == 0, ErrMsg);
43 return Result.ReturnCode;
44 }
45
46 if (ExecutionFailed)
47 *ExecutionFailed = true;
48
49 return -1;
50 }
51
ExecuteNoWait(StringRef Program,ArrayRef<StringRef> Args,Optional<ArrayRef<StringRef>> Env,ArrayRef<Optional<StringRef>> Redirects,unsigned MemoryLimit,std::string * ErrMsg,bool * ExecutionFailed)52 ProcessInfo sys::ExecuteNoWait(StringRef Program, ArrayRef<StringRef> Args,
53 Optional<ArrayRef<StringRef>> Env,
54 ArrayRef<Optional<StringRef>> Redirects,
55 unsigned MemoryLimit, std::string *ErrMsg,
56 bool *ExecutionFailed) {
57 assert(Redirects.empty() || Redirects.size() == 3);
58 ProcessInfo PI;
59 if (ExecutionFailed)
60 *ExecutionFailed = false;
61 if (!Execute(PI, Program, Args, Env, Redirects, MemoryLimit, ErrMsg))
62 if (ExecutionFailed)
63 *ExecutionFailed = true;
64
65 return PI;
66 }
67
commandLineFitsWithinSystemLimits(StringRef Program,ArrayRef<const char * > Args)68 bool sys::commandLineFitsWithinSystemLimits(StringRef Program,
69 ArrayRef<const char *> Args) {
70 SmallVector<StringRef, 8> StringRefArgs;
71 StringRefArgs.reserve(Args.size());
72 for (const char *A : Args)
73 StringRefArgs.emplace_back(A);
74 return commandLineFitsWithinSystemLimits(Program, StringRefArgs);
75 }
76
77 // Include the platform-specific parts of this class.
78 #ifdef LLVM_ON_UNIX
79 #include "Unix/Program.inc"
80 #endif
81 #ifdef _WIN32
82 #include "Windows/Program.inc"
83 #endif
84