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