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