1218885Sdim//===-- Program.cpp - Implement OS Program Concept --------------*- C++ -*-===//
2218885Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6218885Sdim//
7218885Sdim//===----------------------------------------------------------------------===//
8218885Sdim//
9276479Sdim//  This file implements the operating system Program concept.
10218885Sdim//
11218885Sdim//===----------------------------------------------------------------------===//
12218885Sdim
13218885Sdim#include "llvm/Support/Program.h"
14288943Sdim#include "llvm/ADT/StringRef.h"
15341825Sdim#include "llvm/Config/llvm-config.h"
16276479Sdim#include <system_error>
17218885Sdimusing namespace llvm;
18218885Sdimusing namespace sys;
19218885Sdim
20218885Sdim//===----------------------------------------------------------------------===//
21218885Sdim//=== WARNING: Implementation here must contain only TRULY operating system
22218885Sdim//===          independent code.
23218885Sdim//===----------------------------------------------------------------------===//
24218885Sdim
25341825Sdimstatic bool Execute(ProcessInfo &PI, StringRef Program,
26341825Sdim                    ArrayRef<StringRef> Args, Optional<ArrayRef<StringRef>> Env,
27341825Sdim                    ArrayRef<Optional<StringRef>> Redirects,
28327952Sdim                    unsigned MemoryLimit, std::string *ErrMsg);
29261991Sdim
30341825Sdimint sys::ExecuteAndWait(StringRef Program, ArrayRef<StringRef> Args,
31341825Sdim                        Optional<ArrayRef<StringRef>> Env,
32327952Sdim                        ArrayRef<Optional<StringRef>> Redirects,
33327952Sdim                        unsigned SecondsToWait, unsigned MemoryLimit,
34327952Sdim                        std::string *ErrMsg, bool *ExecutionFailed) {
35327952Sdim  assert(Redirects.empty() || Redirects.size() == 3);
36261991Sdim  ProcessInfo PI;
37341825Sdim  if (Execute(PI, Program, Args, Env, Redirects, MemoryLimit, ErrMsg)) {
38261991Sdim    if (ExecutionFailed)
39261991Sdim      *ExecutionFailed = false;
40276479Sdim    ProcessInfo Result = Wait(
41327952Sdim        PI, SecondsToWait, /*WaitUntilTerminates=*/SecondsToWait == 0, ErrMsg);
42261991Sdim    return Result.ReturnCode;
43249423Sdim  }
44261991Sdim
45261991Sdim  if (ExecutionFailed)
46261991Sdim    *ExecutionFailed = true;
47261991Sdim
48249423Sdim  return -1;
49218885Sdim}
50218885Sdim
51341825SdimProcessInfo sys::ExecuteNoWait(StringRef Program, ArrayRef<StringRef> Args,
52341825Sdim                               Optional<ArrayRef<StringRef>> Env,
53327952Sdim                               ArrayRef<Optional<StringRef>> Redirects,
54327952Sdim                               unsigned MemoryLimit, std::string *ErrMsg,
55261991Sdim                               bool *ExecutionFailed) {
56327952Sdim  assert(Redirects.empty() || Redirects.size() == 3);
57261991Sdim  ProcessInfo PI;
58261991Sdim  if (ExecutionFailed)
59261991Sdim    *ExecutionFailed = false;
60341825Sdim  if (!Execute(PI, Program, Args, Env, Redirects, MemoryLimit, ErrMsg))
61261991Sdim    if (ExecutionFailed)
62261991Sdim      *ExecutionFailed = true;
63261991Sdim
64261991Sdim  return PI;
65218885Sdim}
66218885Sdim
67341825Sdimbool sys::commandLineFitsWithinSystemLimits(StringRef Program,
68341825Sdim                                            ArrayRef<const char *> Args) {
69341825Sdim  SmallVector<StringRef, 8> StringRefArgs;
70341825Sdim  StringRefArgs.reserve(Args.size());
71341825Sdim  for (const char *A : Args)
72341825Sdim    StringRefArgs.emplace_back(A);
73341825Sdim  return commandLineFitsWithinSystemLimits(Program, StringRefArgs);
74341825Sdim}
75341825Sdim
76218885Sdim// Include the platform-specific parts of this class.
77218885Sdim#ifdef LLVM_ON_UNIX
78218885Sdim#include "Unix/Program.inc"
79218885Sdim#endif
80341825Sdim#ifdef _WIN32
81218885Sdim#include "Windows/Program.inc"
82218885Sdim#endif
83