xref: /llvm-project/llvm/lib/Support/Program.cpp (revision 48c3341cfe47b5c4d0dca8fac80bfcf1ecaefb88)
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, const char **Args,
27                     const char **Env, ArrayRef<Optional<StringRef>> Redirects,
28                     unsigned MemoryLimit, std::string *ErrMsg);
29 
30 int sys::ExecuteAndWait(StringRef Program, const char **Args, const char **Envp,
31                         ArrayRef<Optional<StringRef>> Redirects,
32                         unsigned SecondsToWait, unsigned MemoryLimit,
33                         std::string *ErrMsg, bool *ExecutionFailed) {
34   assert(Redirects.empty() || Redirects.size() == 3);
35   ProcessInfo PI;
36   if (Execute(PI, Program, Args, Envp, Redirects, MemoryLimit, ErrMsg)) {
37     if (ExecutionFailed)
38       *ExecutionFailed = false;
39     ProcessInfo Result = Wait(
40         PI, SecondsToWait, /*WaitUntilTerminates=*/SecondsToWait == 0, ErrMsg);
41     return Result.ReturnCode;
42   }
43 
44   if (ExecutionFailed)
45     *ExecutionFailed = true;
46 
47   return -1;
48 }
49 
50 ProcessInfo sys::ExecuteNoWait(StringRef Program, const char **Args,
51                                const char **Envp,
52                                ArrayRef<Optional<StringRef>> Redirects,
53                                unsigned MemoryLimit, std::string *ErrMsg,
54                                bool *ExecutionFailed) {
55   assert(Redirects.empty() || Redirects.size() == 3);
56   ProcessInfo PI;
57   if (ExecutionFailed)
58     *ExecutionFailed = false;
59   if (!Execute(PI, Program, Args, Envp, Redirects, MemoryLimit, ErrMsg))
60     if (ExecutionFailed)
61       *ExecutionFailed = true;
62 
63   return PI;
64 }
65 
66 bool sys::commandLineFitsWithinSystemLimits(StringRef Program,
67                                             ArrayRef<const char *> Args) {
68   SmallVector<StringRef, 8> StringRefArgs;
69   StringRefArgs.reserve(Args.size());
70   for (const char *A : Args)
71     StringRefArgs.emplace_back(A);
72   return commandLineFitsWithinSystemLimits(Program, StringRefArgs);
73 }
74 
75 // Include the platform-specific parts of this class.
76 #ifdef LLVM_ON_UNIX
77 #include "Unix/Program.inc"
78 #endif
79 #ifdef _WIN32
80 #include "Windows/Program.inc"
81 #endif
82