13#include "llvm/ADT/SmallVector.h"
14#include "llvm/Support/ConvertUTF.h"
15#include "llvm/Support/Program.h"
24 std::vector<char> &buffer) {
28 for (
const auto &KV : env) {
32 buffer.end(),
reinterpret_cast<const char *
>(warg.c_str()),
33 reinterpret_cast<const char *
>(warg.c_str() + warg.size() + 1));
48 std::vector<llvm::StringRef> args_ref;
49 for (
auto &entry : args.
entries())
50 args_ref.push_back(entry.ref());
52 llvm::ErrorOr<std::wstring> result =
53 llvm::sys::flattenWindowsCommandLine(args_ref);
54 if (result.getError())
66 std::string executable;
67 std::vector<char> environment;
68 STARTUPINFO startupinfo = {};
69 PROCESS_INFORMATION pi = {};
75 startupinfo.cb =
sizeof(startupinfo);
76 startupinfo.dwFlags |= STARTF_USESTDHANDLES;
77 startupinfo.hStdError =
78 stderr_handle ? stderr_handle : ::GetStdHandle(STD_ERROR_HANDLE);
79 startupinfo.hStdInput =
80 stdin_handle ? stdin_handle : ::GetStdHandle(STD_INPUT_HANDLE);
81 startupinfo.hStdOutput =
82 stdout_handle ? stdout_handle : ::GetStdHandle(STD_OUTPUT_HANDLE);
84 const char *hide_console_var =
85 getenv(
"LLDB_LAUNCH_INFERIORS_WITHOUT_CONSOLE");
86 if (hide_console_var &&
87 llvm::StringRef(hide_console_var).equals_insensitive(
"true")) {
88 startupinfo.dwFlags |= STARTF_USESHOWWINDOW;
89 startupinfo.wShowWindow = SW_HIDE;
92 DWORD flags = CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT;
94 flags |= DEBUG_ONLY_THIS_PROCESS;
96 if (launch_info.
GetFlags().
Test(eLaunchFlagDisableSTDIO))
97 flags &= ~CREATE_NEW_CONSOLE;
99 LPVOID env_block =
nullptr;
101 env_block = environment.data();
104 std::wstring wcommandLine;
107 std::wstring wexecutable, wworkingDirectory;
108 llvm::ConvertUTF8toWide(executable, wexecutable);
114 WCHAR *pwcommandLine = wcommandLine.empty() ? nullptr : &wcommandLine[0];
116 BOOL result = ::CreateProcessW(
117 wexecutable.c_str(), pwcommandLine, NULL, NULL, TRUE, flags, env_block,
118 wworkingDirectory.size() == 0 ? NULL : wworkingDirectory.c_str(),
131 ::CloseHandle(pi.hThread);
135 ::CloseHandle(stdin_handle);
137 ::CloseHandle(stdout_handle);
139 ::CloseHandle(stderr_handle);
151 if (action ==
nullptr)
153 SECURITY_ATTRIBUTES secattr = {};
154 secattr.nLength =
sizeof(SECURITY_ATTRIBUTES);
155 secattr.bInheritHandle = TRUE;
157 llvm::StringRef path = action->
GetPath();
159 DWORD share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
162 if (fd == STDIN_FILENO) {
163 access = GENERIC_READ;
164 create = OPEN_EXISTING;
165 flags = FILE_ATTRIBUTE_READONLY;
167 if (fd == STDOUT_FILENO || fd == STDERR_FILENO) {
168 access = GENERIC_WRITE;
169 create = CREATE_ALWAYS;
170 if (fd == STDERR_FILENO)
171 flags = FILE_FLAG_WRITE_THROUGH;
175 llvm::ConvertUTF8toWide(path, wpath);
176 HANDLE result = ::CreateFileW(wpath.c_str(), access, share, &secattr, create,
178 return (result == INVALID_HANDLE_VALUE) ? NULL : result;
static llvm::raw_ostream & error(Stream &strm)
static void CreateEnvironmentBuffer(const Environment &env, std::vector< char > &buffer)
static bool GetFlattenedWindowsCommandString(Args args, std::wstring &command)
A command line argument class.
llvm::ArrayRef< ArgEntry > entries() const
static std::string compose(const value_type &KeyValue)
llvm::StringRef GetPath() const
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
bool Test(ValueType bit) const
Test a single flag bit.
FileSpec & GetExecutableFile()
Environment & GetEnvironment()
const FileAction * GetFileActionForFD(int fd) const
const FileSpec & GetWorkingDirectory() const
HostProcess LaunchProcess(const ProcessLaunchInfo &launch_info, Status &error) override
HANDLE GetStdioHandle(const ProcessLaunchInfo &launch_info, int fd)
A class that represents a running process on the host machine.
@ eErrorTypeWin32
Standard Win32 error codes.