blob: 7a99e0944e532f465004dae06709773aa28d2cfb [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
41 executable = launch_info.GetExecutableFile().GetPath();
42 launch_info.GetArguments().GetQuotedCommandString(commandLine);
43 BOOL result = ::CreateProcessA(executable.c_str(), const_cast<char *>(commandLine.c_str()), NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL,
44 launch_info.GetWorkingDirectory(), &startupinfo, &pi);
45 if (result)
46 {
47 // Do not call CloseHandle on pi.hProcess, since we want to pass that back through the HostProcess.
48 ::CloseHandle(pi.hThread);
49 }
50
51 if (stdin_handle)
52 ::CloseHandle(stdin_handle);
53 if (stdout_handle)
54 ::CloseHandle(stdout_handle);
55 if (stderr_handle)
56 ::CloseHandle(stderr_handle);
57
58 if (!result)
59 error.SetError(::GetLastError(), eErrorTypeWin32);
60 return HostProcess(pi.hProcess);
61}
62
63HANDLE
64ProcessLauncherWindows::GetStdioHandle(const ProcessLaunchInfo &launch_info, int fd)
65{
66 const FileAction *action = launch_info.GetFileActionForFD(fd);
67 if (action == nullptr)
68 return NULL;
69 SECURITY_ATTRIBUTES secattr = {0};
70 secattr.nLength = sizeof(SECURITY_ATTRIBUTES);
71 secattr.bInheritHandle = TRUE;
72
73 const char *path = action->GetPath();
74 DWORD access = 0;
75 DWORD share = FILE_SHARE_READ | FILE_SHARE_WRITE;
76 DWORD create = 0;
77 DWORD flags = 0;
78 if (fd == STDIN_FILENO)
79 {
80 access = GENERIC_READ;
81 create = OPEN_EXISTING;
82 flags = FILE_ATTRIBUTE_READONLY;
83 }
84 if (fd == STDOUT_FILENO || fd == STDERR_FILENO)
85 {
86 access = GENERIC_WRITE;
87 create = CREATE_ALWAYS;
88 if (fd == STDERR_FILENO)
89 flags = FILE_FLAG_WRITE_THROUGH;
90 }
91
92 HANDLE result = ::CreateFile(path, access, share, &secattr, create, flags, NULL);
93 return (result == INVALID_HANDLE_VALUE) ? NULL : result;
94}