blob: 12e03e14b233dd2d03f38c486cbc8323167f6279 [file] [log] [blame]
Zachary Turner172d37d2014-10-14 21:55:08 +00001//===-- ProcessLauncherWindows.cpp ------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Host/HostProcess.h"
11#include "lldb/Host/windows/ProcessLauncherWindows.h"
12#include "lldb/Target/ProcessLaunchInfo.h"
13
14#include <string>
15#include <vector>
16
17using namespace lldb;
18using namespace lldb_private;
19
20HostProcess
21ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info, Error &error)
22{
23 error.Clear();
24
25 std::string executable;
26 std::string commandLine;
27 std::vector<char> environment;
28 STARTUPINFO startupinfo = {0};
29 PROCESS_INFORMATION pi = {0};
30
31 HANDLE stdin_handle = GetStdioHandle(launch_info, STDIN_FILENO);
32 HANDLE stdout_handle = GetStdioHandle(launch_info, STDOUT_FILENO);
33 HANDLE stderr_handle = GetStdioHandle(launch_info, STDERR_FILENO);
34
35 startupinfo.cb = sizeof(startupinfo);
36 startupinfo.dwFlags |= STARTF_USESTDHANDLES;
37 startupinfo.hStdError = stderr_handle;
38 startupinfo.hStdInput = stdin_handle;
39 startupinfo.hStdOutput = stdout_handle;
40
Zachary Turner555a7a62014-12-12 18:10:52 +000041 const char *hide_console_var = getenv("LLDB_LAUNCH_INFERIORS_WITHOUT_CONSOLE");
42 if (hide_console_var && llvm::StringRef(hide_console_var).equals_lower("true"))
43 {
44 startupinfo.dwFlags |= STARTF_USESHOWWINDOW;
45 startupinfo.wShowWindow = SW_HIDE;
46 }
47
Zachary Turner742346a2014-11-05 22:16:28 +000048 DWORD flags = CREATE_NEW_CONSOLE;
49 if (launch_info.GetFlags().Test(eLaunchFlagDebug))
50 flags |= DEBUG_ONLY_THIS_PROCESS;
51
Zachary Turner172d37d2014-10-14 21:55:08 +000052 executable = launch_info.GetExecutableFile().GetPath();
53 launch_info.GetArguments().GetQuotedCommandString(commandLine);
Zachary Turner742346a2014-11-05 22:16:28 +000054 BOOL result = ::CreateProcessA(executable.c_str(), const_cast<char *>(commandLine.c_str()), NULL, NULL, TRUE, flags, NULL,
Zachary Turner172d37d2014-10-14 21:55:08 +000055 launch_info.GetWorkingDirectory(), &startupinfo, &pi);
56 if (result)
57 {
58 // Do not call CloseHandle on pi.hProcess, since we want to pass that back through the HostProcess.
59 ::CloseHandle(pi.hThread);
60 }
61
62 if (stdin_handle)
63 ::CloseHandle(stdin_handle);
64 if (stdout_handle)
65 ::CloseHandle(stdout_handle);
66 if (stderr_handle)
67 ::CloseHandle(stderr_handle);
68
69 if (!result)
70 error.SetError(::GetLastError(), eErrorTypeWin32);
71 return HostProcess(pi.hProcess);
72}
73
74HANDLE
75ProcessLauncherWindows::GetStdioHandle(const ProcessLaunchInfo &launch_info, int fd)
76{
77 const FileAction *action = launch_info.GetFileActionForFD(fd);
78 if (action == nullptr)
79 return NULL;
80 SECURITY_ATTRIBUTES secattr = {0};
81 secattr.nLength = sizeof(SECURITY_ATTRIBUTES);
82 secattr.bInheritHandle = TRUE;
83
84 const char *path = action->GetPath();
85 DWORD access = 0;
86 DWORD share = FILE_SHARE_READ | FILE_SHARE_WRITE;
87 DWORD create = 0;
88 DWORD flags = 0;
89 if (fd == STDIN_FILENO)
90 {
91 access = GENERIC_READ;
92 create = OPEN_EXISTING;
93 flags = FILE_ATTRIBUTE_READONLY;
94 }
95 if (fd == STDOUT_FILENO || fd == STDERR_FILENO)
96 {
97 access = GENERIC_WRITE;
98 create = CREATE_ALWAYS;
99 if (fd == STDERR_FILENO)
100 flags = FILE_FLAG_WRITE_THROUGH;
101 }
102
103 HANDLE result = ::CreateFile(path, access, share, &secattr, create, flags, NULL);
104 return (result == INVALID_HANDLE_VALUE) ? NULL : result;
105}