12754fe60SDimitry Andric //===-- Program.cpp - Implement OS Program Concept --------------*- C++ -*-===//
22754fe60SDimitry Andric //
32754fe60SDimitry Andric //                     The LLVM Compiler Infrastructure
42754fe60SDimitry Andric //
52754fe60SDimitry Andric // This file is distributed under the University of Illinois Open Source
62754fe60SDimitry Andric // License. See LICENSE.TXT for details.
72754fe60SDimitry Andric //
82754fe60SDimitry Andric //===----------------------------------------------------------------------===//
92754fe60SDimitry Andric //
1091bc56edSDimitry Andric //  This file implements the operating system Program concept.
112754fe60SDimitry Andric //
122754fe60SDimitry Andric //===----------------------------------------------------------------------===//
132754fe60SDimitry Andric 
142754fe60SDimitry Andric #include "llvm/Support/Program.h"
15ff0cc061SDimitry Andric #include "llvm/ADT/StringRef.h"
16*4ba319b5SDimitry Andric #include "llvm/Config/llvm-config.h"
1791bc56edSDimitry Andric #include <system_error>
182754fe60SDimitry Andric using namespace llvm;
192754fe60SDimitry Andric using namespace sys;
202754fe60SDimitry Andric 
212754fe60SDimitry Andric //===----------------------------------------------------------------------===//
222754fe60SDimitry Andric //=== WARNING: Implementation here must contain only TRULY operating system
232754fe60SDimitry Andric //===          independent code.
242754fe60SDimitry Andric //===----------------------------------------------------------------------===//
252754fe60SDimitry Andric 
26*4ba319b5SDimitry Andric static bool Execute(ProcessInfo &PI, StringRef Program,
27*4ba319b5SDimitry Andric                     ArrayRef<StringRef> Args, Optional<ArrayRef<StringRef>> Env,
28*4ba319b5SDimitry Andric                     ArrayRef<Optional<StringRef>> Redirects,
292cab237bSDimitry Andric                     unsigned MemoryLimit, std::string *ErrMsg);
30f785676fSDimitry Andric 
ExecuteAndWait(StringRef Program,ArrayRef<StringRef> Args,Optional<ArrayRef<StringRef>> Env,ArrayRef<Optional<StringRef>> Redirects,unsigned SecondsToWait,unsigned MemoryLimit,std::string * ErrMsg,bool * ExecutionFailed)31*4ba319b5SDimitry Andric int sys::ExecuteAndWait(StringRef Program, ArrayRef<StringRef> Args,
32*4ba319b5SDimitry Andric                         Optional<ArrayRef<StringRef>> Env,
332cab237bSDimitry Andric                         ArrayRef<Optional<StringRef>> Redirects,
342cab237bSDimitry Andric                         unsigned SecondsToWait, unsigned MemoryLimit,
352cab237bSDimitry Andric                         std::string *ErrMsg, bool *ExecutionFailed) {
362cab237bSDimitry Andric   assert(Redirects.empty() || Redirects.size() == 3);
37f785676fSDimitry Andric   ProcessInfo PI;
38*4ba319b5SDimitry Andric   if (Execute(PI, Program, Args, Env, Redirects, MemoryLimit, ErrMsg)) {
39f785676fSDimitry Andric     if (ExecutionFailed)
40f785676fSDimitry Andric       *ExecutionFailed = false;
4191bc56edSDimitry Andric     ProcessInfo Result = Wait(
422cab237bSDimitry Andric         PI, SecondsToWait, /*WaitUntilTerminates=*/SecondsToWait == 0, ErrMsg);
43f785676fSDimitry Andric     return Result.ReturnCode;
44139f7f9bSDimitry Andric   }
45f785676fSDimitry Andric 
46f785676fSDimitry Andric   if (ExecutionFailed)
47f785676fSDimitry Andric     *ExecutionFailed = true;
48f785676fSDimitry Andric 
492754fe60SDimitry Andric   return -1;
502754fe60SDimitry Andric }
512754fe60SDimitry Andric 
ExecuteNoWait(StringRef Program,ArrayRef<StringRef> Args,Optional<ArrayRef<StringRef>> Env,ArrayRef<Optional<StringRef>> Redirects,unsigned MemoryLimit,std::string * ErrMsg,bool * ExecutionFailed)52*4ba319b5SDimitry Andric ProcessInfo sys::ExecuteNoWait(StringRef Program, ArrayRef<StringRef> Args,
53*4ba319b5SDimitry Andric                                Optional<ArrayRef<StringRef>> Env,
542cab237bSDimitry Andric                                ArrayRef<Optional<StringRef>> Redirects,
552cab237bSDimitry Andric                                unsigned MemoryLimit, std::string *ErrMsg,
56f785676fSDimitry Andric                                bool *ExecutionFailed) {
572cab237bSDimitry Andric   assert(Redirects.empty() || Redirects.size() == 3);
58f785676fSDimitry Andric   ProcessInfo PI;
59f785676fSDimitry Andric   if (ExecutionFailed)
60f785676fSDimitry Andric     *ExecutionFailed = false;
61*4ba319b5SDimitry Andric   if (!Execute(PI, Program, Args, Env, Redirects, MemoryLimit, ErrMsg))
62f785676fSDimitry Andric     if (ExecutionFailed)
63f785676fSDimitry Andric       *ExecutionFailed = true;
64f785676fSDimitry Andric 
65f785676fSDimitry Andric   return PI;
662754fe60SDimitry Andric }
672754fe60SDimitry Andric 
commandLineFitsWithinSystemLimits(StringRef Program,ArrayRef<const char * > Args)68*4ba319b5SDimitry Andric bool sys::commandLineFitsWithinSystemLimits(StringRef Program,
69*4ba319b5SDimitry Andric                                             ArrayRef<const char *> Args) {
70*4ba319b5SDimitry Andric   SmallVector<StringRef, 8> StringRefArgs;
71*4ba319b5SDimitry Andric   StringRefArgs.reserve(Args.size());
72*4ba319b5SDimitry Andric   for (const char *A : Args)
73*4ba319b5SDimitry Andric     StringRefArgs.emplace_back(A);
74*4ba319b5SDimitry Andric   return commandLineFitsWithinSystemLimits(Program, StringRefArgs);
75*4ba319b5SDimitry Andric }
76*4ba319b5SDimitry Andric 
772754fe60SDimitry Andric // Include the platform-specific parts of this class.
782754fe60SDimitry Andric #ifdef LLVM_ON_UNIX
792754fe60SDimitry Andric #include "Unix/Program.inc"
802754fe60SDimitry Andric #endif
81*4ba319b5SDimitry Andric #ifdef _WIN32
822754fe60SDimitry Andric #include "Windows/Program.inc"
832754fe60SDimitry Andric #endif
84