123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- //===-- Program.cpp - Implement OS Program Concept --------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file implements the operating system Program concept.
- //
- //===----------------------------------------------------------------------===//
- #include "llvm/Support/Program.h"
- #include "llvm/ADT/StringRef.h"
- #include "llvm/Config/llvm-config.h"
- #include "llvm/Support/raw_ostream.h"
- #include <system_error>
- using namespace llvm;
- using namespace sys;
- //===----------------------------------------------------------------------===//
- //=== WARNING: Implementation here must contain only TRULY operating system
- //=== independent code.
- //===----------------------------------------------------------------------===//
- static bool Execute(ProcessInfo &PI, StringRef Program,
- ArrayRef<StringRef> Args, Optional<ArrayRef<StringRef>> Env,
- ArrayRef<Optional<StringRef>> Redirects,
- unsigned MemoryLimit, std::string *ErrMsg,
- BitVector *AffinityMask);
- int sys::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) {
- assert(Redirects.empty() || Redirects.size() == 3);
- ProcessInfo PI;
- if (Execute(PI, Program, Args, Env, Redirects, MemoryLimit, ErrMsg,
- AffinityMask)) {
- if (ExecutionFailed)
- *ExecutionFailed = false;
- ProcessInfo Result =
- Wait(PI, SecondsToWait, /*WaitUntilTerminates=*/SecondsToWait == 0,
- ErrMsg, ProcStat);
- return Result.ReturnCode;
- }
- if (ExecutionFailed)
- *ExecutionFailed = true;
- return -1;
- }
- ProcessInfo sys::ExecuteNoWait(StringRef Program, ArrayRef<StringRef> Args,
- Optional<ArrayRef<StringRef>> Env,
- ArrayRef<Optional<StringRef>> Redirects,
- unsigned MemoryLimit, std::string *ErrMsg,
- bool *ExecutionFailed, BitVector *AffinityMask) {
- assert(Redirects.empty() || Redirects.size() == 3);
- ProcessInfo PI;
- if (ExecutionFailed)
- *ExecutionFailed = false;
- if (!Execute(PI, Program, Args, Env, Redirects, MemoryLimit, ErrMsg,
- AffinityMask))
- if (ExecutionFailed)
- *ExecutionFailed = true;
- return PI;
- }
- bool sys::commandLineFitsWithinSystemLimits(StringRef Program,
- ArrayRef<const char *> Args) {
- SmallVector<StringRef, 8> StringRefArgs;
- StringRefArgs.reserve(Args.size());
- for (const char *A : Args)
- StringRefArgs.emplace_back(A);
- return commandLineFitsWithinSystemLimits(Program, StringRefArgs);
- }
- void sys::printArg(raw_ostream &OS, StringRef Arg, bool Quote) {
- const bool Escape = Arg.find_first_of(" \"\\$") != StringRef::npos;
- if (!Quote && !Escape) {
- OS << Arg;
- return;
- }
- // Quote and escape. This isn't really complete, but good enough.
- OS << '"';
- for (const auto c : Arg) {
- if (c == '"' || c == '\\' || c == '$')
- OS << '\\';
- OS << c;
- }
- OS << '"';
- }
- // Include the platform-specific parts of this class.
- #ifdef LLVM_ON_UNIX
- #include "Unix/Program.inc"
- #endif
- #ifdef _WIN32
- #include "Windows/Program.inc"
- #endif
|