llvm/lib/Support/Program.cpp
Zachary Turner 861985beca [Support] Expose flattenWindowsCommandLine.
This function was internal to Program.inc, but I've needed this
on several occasions when I've had to use CreateProcess without
llvm's sys::Execute functions.  In doing so, I noticed that the
function was written using unsafe C-string access and was pretty
hard to understand / make sense of, so I've also re-written the
functions to use more modern LLVM constructs.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@334353 91177308-0d34-0410-b5e6-96231b3b80d8
2018-06-09 22:44:44 +00:00

82 lines
2.9 KiB
C++

//===-- Program.cpp - Implement OS Program Concept --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// 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 <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, const char **Args,
const char **Env, ArrayRef<Optional<StringRef>> Redirects,
unsigned MemoryLimit, std::string *ErrMsg);
int sys::ExecuteAndWait(StringRef Program, const char **Args, const char **Envp,
ArrayRef<Optional<StringRef>> Redirects,
unsigned SecondsToWait, unsigned MemoryLimit,
std::string *ErrMsg, bool *ExecutionFailed) {
assert(Redirects.empty() || Redirects.size() == 3);
ProcessInfo PI;
if (Execute(PI, Program, Args, Envp, Redirects, MemoryLimit, ErrMsg)) {
if (ExecutionFailed)
*ExecutionFailed = false;
ProcessInfo Result = Wait(
PI, SecondsToWait, /*WaitUntilTerminates=*/SecondsToWait == 0, ErrMsg);
return Result.ReturnCode;
}
if (ExecutionFailed)
*ExecutionFailed = true;
return -1;
}
ProcessInfo sys::ExecuteNoWait(StringRef Program, const char **Args,
const char **Envp,
ArrayRef<Optional<StringRef>> Redirects,
unsigned MemoryLimit, std::string *ErrMsg,
bool *ExecutionFailed) {
assert(Redirects.empty() || Redirects.size() == 3);
ProcessInfo PI;
if (ExecutionFailed)
*ExecutionFailed = false;
if (!Execute(PI, Program, Args, Envp, Redirects, MemoryLimit, ErrMsg))
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);
}
// Include the platform-specific parts of this class.
#ifdef LLVM_ON_UNIX
#include "Unix/Program.inc"
#endif
#ifdef _WIN32
#include "Windows/Program.inc"
#endif