From f490bec4a1356a0d3f8269eae5cb2c7cbcd3174e Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Mon, 4 Aug 2014 23:31:21 +0000 Subject: [PATCH] Teach ProcessWindows plugin to support stdio i/o redirection. llvm-svn: 214816 --- .../Plugins/Process/Windows/ProcessWindows.cpp | 72 ++++++++++++++++++---- 1 file changed, 61 insertions(+), 11 deletions(-) diff --git a/lldb/source/Plugins/Process/Windows/ProcessWindows.cpp b/lldb/source/Plugins/Process/Windows/ProcessWindows.cpp index 8aeed4b..d421025 100644 --- a/lldb/source/Plugins/Process/Windows/ProcessWindows.cpp +++ b/lldb/source/Plugins/Process/Windows/ProcessWindows.cpp @@ -25,6 +25,42 @@ using namespace lldb; using namespace lldb_private; +namespace +{ +HANDLE +GetStdioHandle(ProcessLaunchInfo &launch_info, int fd) +{ + const ProcessLaunchInfo::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; + 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; + } + + HANDLE result = ::CreateFile(path, access, share, &secattr, create, flags, NULL); + return (result == INVALID_HANDLE_VALUE) ? NULL : result; +} +} + //------------------------------------------------------------------------------ // Static functions. @@ -91,20 +127,34 @@ ProcessWindows::DoLaunch(Module *exe_module, std::vector 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; + startupinfo.hStdInput = stdin_handle; + startupinfo.hStdOutput = stdout_handle; + executable = launch_info.GetExecutableFile().GetPath(); launch_info.GetArguments().GetQuotedCommandString(commandLine); - BOOL result = ::CreateProcessA(executable.c_str(), - const_cast(commandLine.c_str()), - NULL, - NULL, - FALSE, - CREATE_NEW_CONSOLE, - NULL, - launch_info.GetWorkingDirectory(), - &startupinfo, - &pi); + BOOL result = ::CreateProcessA(executable.c_str(), const_cast(commandLine.c_str()), NULL, NULL, TRUE, + CREATE_NEW_CONSOLE, NULL, launch_info.GetWorkingDirectory(), &startupinfo, &pi); + if (result) + { + ::CloseHandle(pi.hProcess); + ::CloseHandle(pi.hThread); + } + + if (stdin_handle) + ::CloseHandle(stdin_handle); + if (stdout_handle) + ::CloseHandle(stdout_handle); + if (stderr_handle) + ::CloseHandle(stderr_handle); + Error error; if (!result) error.SetErrorToErrno(); -- 2.7.4