1414#include " llvm/ADT/SmallVector.h"
1515#include " llvm/Support/ConvertUTF.h"
1616#include " llvm/Support/Program.h"
17+ #include " llvm/Support/WindowsError.h"
1718
1819#include < string>
1920#include < vector>
@@ -86,10 +87,14 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
8687 error.Clear ();
8788
8889 std::string executable;
90+ std::vector<HANDLE> inherited_handles;
8991 STARTUPINFOEXW startupinfoex = {};
9092 STARTUPINFOW &startupinfo = startupinfoex.StartupInfo ;
9193 PROCESS_INFORMATION pi = {};
9294
95+ startupinfo.cb = sizeof (startupinfoex);
96+ startupinfo.dwFlags |= STARTF_USESTDHANDLES;
97+
9398 HANDLE stdin_handle = GetStdioHandle (launch_info, STDIN_FILENO);
9499 HANDLE stdout_handle = GetStdioHandle (launch_info, STDOUT_FILENO);
95100 HANDLE stderr_handle = GetStdioHandle (launch_info, STDERR_FILENO);
@@ -102,22 +107,13 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
102107 ::CloseHandle (stderr_handle);
103108 });
104109
105- startupinfo.cb = sizeof (startupinfoex);
106- startupinfo.dwFlags |= STARTF_USESTDHANDLES;
107- startupinfo.hStdError =
108- stderr_handle ? stderr_handle : ::GetStdHandle (STD_ERROR_HANDLE);
109- startupinfo.hStdInput =
110- stdin_handle ? stdin_handle : ::GetStdHandle (STD_INPUT_HANDLE);
111- startupinfo.hStdOutput =
112- stdout_handle ? stdout_handle : ::GetStdHandle (STD_OUTPUT_HANDLE);
113-
114- std::vector<HANDLE> inherited_handles;
115- if (startupinfo.hStdError )
116- inherited_handles.push_back (startupinfo.hStdError );
117- if (startupinfo.hStdInput )
118- inherited_handles.push_back (startupinfo.hStdInput );
119- if (startupinfo.hStdOutput )
120- inherited_handles.push_back (startupinfo.hStdOutput );
110+ auto inherited_handles_or_err = GetInheritedHandles (
111+ launch_info, startupinfoex, stdout_handle, stderr_handle, stdin_handle);
112+ if (!inherited_handles_or_err) {
113+ error = Status (inherited_handles_or_err.getError ());
114+ return HostProcess ();
115+ }
116+ inherited_handles = *inherited_handles_or_err;
121117
122118 SIZE_T attributelist_size = 0 ;
123119 InitializeProcThreadAttributeList (/* lpAttributeList=*/ nullptr ,
@@ -136,22 +132,6 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
136132 }
137133 auto delete_attributelist = llvm::make_scope_exit (
138134 [&] { DeleteProcThreadAttributeList (startupinfoex.lpAttributeList ); });
139- for (size_t i = 0 ; i < launch_info.GetNumFileActions (); ++i) {
140- const FileAction *act = launch_info.GetFileActionAtIndex (i);
141- if (act->GetAction () == FileAction::eFileActionDuplicate &&
142- act->GetFD () == act->GetActionArgument ())
143- inherited_handles.push_back (reinterpret_cast <HANDLE>(act->GetFD ()));
144- }
145- if (!inherited_handles.empty ()) {
146- if (!UpdateProcThreadAttribute (
147- startupinfoex.lpAttributeList , /* dwFlags=*/ 0 ,
148- PROC_THREAD_ATTRIBUTE_HANDLE_LIST, inherited_handles.data (),
149- inherited_handles.size () * sizeof (HANDLE),
150- /* lpPreviousValue=*/ nullptr , /* lpReturnSize=*/ nullptr )) {
151- error = Status (::GetLastError (), eErrorTypeWin32);
152- return HostProcess ();
153- }
154- }
155135
156136 const char *hide_console_var =
157137 getenv (" LLDB_LAUNCH_INFERIORS_WITHOUT_CONSOLE" );
@@ -215,6 +195,46 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
215195 return HostProcess (pi.hProcess );
216196}
217197
198+ llvm::ErrorOr<std::vector<HANDLE>> ProcessLauncherWindows::GetInheritedHandles (
199+ const ProcessLaunchInfo &launch_info, STARTUPINFOEXW &startupinfoex,
200+ HANDLE stdout_handle, HANDLE stderr_handle, HANDLE stdin_handle) {
201+ std::vector<HANDLE> inherited_handles;
202+ STARTUPINFOW startupinfo = startupinfoex.StartupInfo ;
203+
204+ startupinfo.hStdError =
205+ stderr_handle ? stderr_handle : GetStdHandle (STD_ERROR_HANDLE);
206+ startupinfo.hStdInput =
207+ stdin_handle ? stdin_handle : GetStdHandle (STD_INPUT_HANDLE);
208+ startupinfo.hStdOutput =
209+ stdout_handle ? stdout_handle : GetStdHandle (STD_OUTPUT_HANDLE);
210+
211+ if (startupinfo.hStdError )
212+ inherited_handles.push_back (startupinfo.hStdError );
213+ if (startupinfo.hStdInput )
214+ inherited_handles.push_back (startupinfo.hStdInput );
215+ if (startupinfo.hStdOutput )
216+ inherited_handles.push_back (startupinfo.hStdOutput );
217+
218+ for (size_t i = 0 ; i < launch_info.GetNumFileActions (); ++i) {
219+ const FileAction *act = launch_info.GetFileActionAtIndex (i);
220+ if (act->GetAction () == FileAction::eFileActionDuplicate &&
221+ act->GetFD () == act->GetActionArgument ())
222+ inherited_handles.push_back (reinterpret_cast <HANDLE>(act->GetFD ()));
223+ }
224+
225+ if (inherited_handles.empty ())
226+ return inherited_handles;
227+
228+ if (!UpdateProcThreadAttribute (
229+ startupinfoex.lpAttributeList , /* dwFlags=*/ 0 ,
230+ PROC_THREAD_ATTRIBUTE_HANDLE_LIST, inherited_handles.data (),
231+ inherited_handles.size () * sizeof (HANDLE),
232+ /* lpPreviousValue=*/ nullptr , /* lpReturnSize=*/ nullptr ))
233+ return llvm::mapWindowsError (::GetLastError ());
234+
235+ return inherited_handles;
236+ }
237+
218238HANDLE
219239ProcessLauncherWindows::GetStdioHandle (const ProcessLaunchInfo &launch_info,
220240 int fd) {
0 commit comments