1 //===-- Program.cpp - Implement OS Program Concept --------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the operating system Program concept.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "llvm/Support/Program.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/Config/llvm-config.h"
16 #include "llvm/Support/raw_ostream.h"
17 using namespace llvm;
18 using namespace sys;
19
20 //===----------------------------------------------------------------------===//
21 //=== WARNING: Implementation here must contain only TRULY operating system
22 //=== independent code.
23 //===----------------------------------------------------------------------===//
24
25 static bool Execute(ProcessInfo &PI, StringRef Program,
26 ArrayRef<StringRef> Args, Optional<ArrayRef<StringRef>> Env,
27 ArrayRef<Optional<StringRef>> Redirects,
28 unsigned MemoryLimit, std::string *ErrMsg,
29 BitVector *AffinityMask);
30
ExecuteAndWait(StringRef Program,ArrayRef<StringRef> Args,Optional<ArrayRef<StringRef>> Env,ArrayRef<Optional<StringRef>> Redirects,unsigned SecondsToWait,unsigned MemoryLimit,std::string * ErrMsg,bool * ExecutionFailed,Optional<ProcessStatistics> * ProcStat,BitVector * AffinityMask)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 Optional<ProcessStatistics> *ProcStat,
37 BitVector *AffinityMask) {
38 assert(Redirects.empty() || Redirects.size() == 3);
39 ProcessInfo PI;
40 if (Execute(PI, Program, Args, Env, Redirects, MemoryLimit, ErrMsg,
41 AffinityMask)) {
42 if (ExecutionFailed)
43 *ExecutionFailed = false;
44 ProcessInfo Result =
45 Wait(PI, SecondsToWait, /*WaitUntilTerminates=*/SecondsToWait == 0,
46 ErrMsg, ProcStat);
47 return Result.ReturnCode;
48 }
49
50 if (ExecutionFailed)
51 *ExecutionFailed = true;
52
53 return -1;
54 }
55
ExecuteNoWait(StringRef Program,ArrayRef<StringRef> Args,Optional<ArrayRef<StringRef>> Env,ArrayRef<Optional<StringRef>> Redirects,unsigned MemoryLimit,std::string * ErrMsg,bool * ExecutionFailed,BitVector * AffinityMask)56 ProcessInfo sys::ExecuteNoWait(StringRef Program, ArrayRef<StringRef> Args,
57 Optional<ArrayRef<StringRef>> Env,
58 ArrayRef<Optional<StringRef>> Redirects,
59 unsigned MemoryLimit, std::string *ErrMsg,
60 bool *ExecutionFailed, BitVector *AffinityMask) {
61 assert(Redirects.empty() || Redirects.size() == 3);
62 ProcessInfo PI;
63 if (ExecutionFailed)
64 *ExecutionFailed = false;
65 if (!Execute(PI, Program, Args, Env, Redirects, MemoryLimit, ErrMsg,
66 AffinityMask))
67 if (ExecutionFailed)
68 *ExecutionFailed = true;
69
70 return PI;
71 }
72
commandLineFitsWithinSystemLimits(StringRef Program,ArrayRef<const char * > Args)73 bool sys::commandLineFitsWithinSystemLimits(StringRef Program,
74 ArrayRef<const char *> Args) {
75 SmallVector<StringRef, 8> StringRefArgs;
76 StringRefArgs.reserve(Args.size());
77 for (const char *A : Args)
78 StringRefArgs.emplace_back(A);
79 return commandLineFitsWithinSystemLimits(Program, StringRefArgs);
80 }
81
printArg(raw_ostream & OS,StringRef Arg,bool Quote)82 void sys::printArg(raw_ostream &OS, StringRef Arg, bool Quote) {
83 const bool Escape = Arg.find_first_of(" \"\\$") != StringRef::npos;
84
85 if (!Quote && !Escape) {
86 OS << Arg;
87 return;
88 }
89
90 // Quote and escape. This isn't really complete, but good enough.
91 OS << '"';
92 for (const auto c : Arg) {
93 if (c == '"' || c == '\\' || c == '$')
94 OS << '\\';
95 OS << c;
96 }
97 OS << '"';
98 }
99
100 // Include the platform-specific parts of this class.
101 #ifdef LLVM_ON_UNIX
102 #include "Unix/Program.inc"
103 #endif
104 #ifdef _WIN32
105 #include "Windows/Program.inc"
106 #endif
107