
*** to conform to clang-format’s LLVM style. This kind of mass change has *** two obvious implications: Firstly, merging this particular commit into a downstream fork may be a huge effort. Alternatively, it may be worth merging all changes up to this commit, performing the same reformatting operation locally, and then discarding the merge for this particular commit. The commands used to accomplish this reformatting were as follows (with current working directory as the root of the repository): find . \( -iname "*.c" -or -iname "*.cpp" -or -iname "*.h" -or -iname "*.mm" \) -exec clang-format -i {} + find . -iname "*.py" -exec autopep8 --in-place --aggressive --aggressive {} + ; The version of clang-format used was 3.9.0, and autopep8 was 1.2.4. Secondly, “blame” style tools will generally point to this commit instead of a meaningful prior commit. There are alternatives available that will attempt to look through this change and find the appropriate prior commit. YMMV. llvm-svn: 280751
150 lines
4.9 KiB
C++
150 lines
4.9 KiB
C++
//===-- ProcessLauncherWindows.cpp ------------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "lldb/Host/windows/ProcessLauncherWindows.h"
|
|
#include "lldb/Host/HostProcess.h"
|
|
#include "lldb/Target/ProcessLaunchInfo.h"
|
|
|
|
#include "llvm/ADT/SmallVector.h"
|
|
#include "llvm/Support/ConvertUTF.h"
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
namespace {
|
|
void CreateEnvironmentBuffer(const Args &env, std::vector<char> &buffer) {
|
|
if (env.GetArgumentCount() == 0)
|
|
return;
|
|
|
|
// Environment buffer is a null terminated list of null terminated strings
|
|
for (int i = 0; i < env.GetArgumentCount(); ++i) {
|
|
std::wstring warg;
|
|
if (llvm::ConvertUTF8toWide(env.GetArgumentAtIndex(i), warg)) {
|
|
buffer.insert(buffer.end(), (char *)warg.c_str(),
|
|
(char *)(warg.c_str() + warg.size() + 1));
|
|
}
|
|
}
|
|
// One null wchar_t (to end the block) is two null bytes
|
|
buffer.push_back(0);
|
|
buffer.push_back(0);
|
|
}
|
|
}
|
|
|
|
HostProcess
|
|
ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
|
|
Error &error) {
|
|
error.Clear();
|
|
|
|
std::string executable;
|
|
std::string commandLine;
|
|
std::vector<char> environment;
|
|
STARTUPINFO startupinfo = {0};
|
|
PROCESS_INFORMATION pi = {0};
|
|
|
|
HANDLE stdin_handle = GetStdioHandle(launch_info, STDIN_FILENO);
|
|
HANDLE stdout_handle = GetStdioHandle(launch_info, STDOUT_FILENO);
|
|
HANDLE stderr_handle = GetStdioHandle(launch_info, STDERR_FILENO);
|
|
|
|
startupinfo.cb = sizeof(startupinfo);
|
|
startupinfo.dwFlags |= STARTF_USESTDHANDLES;
|
|
startupinfo.hStdError =
|
|
stderr_handle ? stderr_handle : ::GetStdHandle(STD_ERROR_HANDLE);
|
|
startupinfo.hStdInput =
|
|
stdin_handle ? stdin_handle : ::GetStdHandle(STD_INPUT_HANDLE);
|
|
startupinfo.hStdOutput =
|
|
stdout_handle ? stdout_handle : ::GetStdHandle(STD_OUTPUT_HANDLE);
|
|
|
|
const char *hide_console_var =
|
|
getenv("LLDB_LAUNCH_INFERIORS_WITHOUT_CONSOLE");
|
|
if (hide_console_var &&
|
|
llvm::StringRef(hide_console_var).equals_lower("true")) {
|
|
startupinfo.dwFlags |= STARTF_USESHOWWINDOW;
|
|
startupinfo.wShowWindow = SW_HIDE;
|
|
}
|
|
|
|
DWORD flags = CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT;
|
|
if (launch_info.GetFlags().Test(eLaunchFlagDebug))
|
|
flags |= DEBUG_ONLY_THIS_PROCESS;
|
|
|
|
auto &env = const_cast<Args &>(launch_info.GetEnvironmentEntries());
|
|
LPVOID env_block = nullptr;
|
|
::CreateEnvironmentBuffer(env, environment);
|
|
if (!environment.empty())
|
|
env_block = environment.data();
|
|
|
|
executable = launch_info.GetExecutableFile().GetPath();
|
|
launch_info.GetArguments().GetQuotedCommandString(commandLine);
|
|
|
|
std::wstring wexecutable, wcommandLine, wworkingDirectory;
|
|
llvm::ConvertUTF8toWide(executable, wexecutable);
|
|
llvm::ConvertUTF8toWide(commandLine, wcommandLine);
|
|
llvm::ConvertUTF8toWide(launch_info.GetWorkingDirectory().GetCString(),
|
|
wworkingDirectory);
|
|
|
|
wcommandLine.resize(PATH_MAX); // Needs to be over-allocated because
|
|
// CreateProcessW can modify it
|
|
BOOL result = ::CreateProcessW(
|
|
wexecutable.c_str(), &wcommandLine[0], NULL, NULL, TRUE, flags, env_block,
|
|
wworkingDirectory.size() == 0 ? NULL : wworkingDirectory.c_str(),
|
|
&startupinfo, &pi);
|
|
if (result) {
|
|
// Do not call CloseHandle on pi.hProcess, since we want to pass that back
|
|
// through the HostProcess.
|
|
::CloseHandle(pi.hThread);
|
|
}
|
|
|
|
if (stdin_handle)
|
|
::CloseHandle(stdin_handle);
|
|
if (stdout_handle)
|
|
::CloseHandle(stdout_handle);
|
|
if (stderr_handle)
|
|
::CloseHandle(stderr_handle);
|
|
|
|
if (!result)
|
|
error.SetError(::GetLastError(), eErrorTypeWin32);
|
|
return HostProcess(pi.hProcess);
|
|
}
|
|
|
|
HANDLE
|
|
ProcessLauncherWindows::GetStdioHandle(const ProcessLaunchInfo &launch_info,
|
|
int fd) {
|
|
const FileAction *action = launch_info.GetFileActionForFD(fd);
|
|
if (action == nullptr)
|
|
return NULL;
|
|
SECURITY_ATTRIBUTES secattr = {0};
|
|
secattr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
|
secattr.bInheritHandle = TRUE;
|
|
|
|
const char *path = action->GetPath();
|
|
DWORD access = 0;
|
|
DWORD share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
|
|
DWORD create = 0;
|
|
DWORD flags = 0;
|
|
if (fd == STDIN_FILENO) {
|
|
access = GENERIC_READ;
|
|
create = OPEN_EXISTING;
|
|
flags = FILE_ATTRIBUTE_READONLY;
|
|
}
|
|
if (fd == STDOUT_FILENO || fd == STDERR_FILENO) {
|
|
access = GENERIC_WRITE;
|
|
create = CREATE_ALWAYS;
|
|
if (fd == STDERR_FILENO)
|
|
flags = FILE_FLAG_WRITE_THROUGH;
|
|
}
|
|
|
|
std::wstring wpath;
|
|
llvm::ConvertUTF8toWide(path, wpath);
|
|
HANDLE result = ::CreateFileW(wpath.c_str(), access, share, &secattr, create,
|
|
flags, NULL);
|
|
return (result == INVALID_HANDLE_VALUE) ? NULL : result;
|
|
}
|