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