67 std::string executable;
68 std::vector<char> environment;
69 STARTUPINFOEX startupinfoex = {};
70 STARTUPINFO &startupinfo = startupinfoex.StartupInfo;
71 PROCESS_INFORMATION pi = {};
76 auto close_handles = llvm::make_scope_exit([&] {
78 ::CloseHandle(stdin_handle);
80 ::CloseHandle(stdout_handle);
82 ::CloseHandle(stderr_handle);
85 startupinfo.cb =
sizeof(startupinfoex);
86 startupinfo.dwFlags |= STARTF_USESTDHANDLES;
87 startupinfo.hStdError =
88 stderr_handle ? stderr_handle : ::GetStdHandle(STD_ERROR_HANDLE);
89 startupinfo.hStdInput =
90 stdin_handle ? stdin_handle : ::GetStdHandle(STD_INPUT_HANDLE);
91 startupinfo.hStdOutput =
92 stdout_handle ? stdout_handle : ::GetStdHandle(STD_OUTPUT_HANDLE);
94 std::vector<HANDLE> inherited_handles;
95 if (startupinfo.hStdError)
96 inherited_handles.push_back(startupinfo.hStdError);
97 if (startupinfo.hStdInput)
98 inherited_handles.push_back(startupinfo.hStdInput);
99 if (startupinfo.hStdOutput)
100 inherited_handles.push_back(startupinfo.hStdOutput);
102 SIZE_T attributelist_size = 0;
103 InitializeProcThreadAttributeList(
nullptr,
105 &attributelist_size);
107 startupinfoex.lpAttributeList =
108 static_cast<LPPROC_THREAD_ATTRIBUTE_LIST
>(malloc(attributelist_size));
109 auto free_attributelist =
110 llvm::make_scope_exit([&] { free(startupinfoex.lpAttributeList); });
111 if (!InitializeProcThreadAttributeList(startupinfoex.lpAttributeList,
113 &attributelist_size)) {
117 auto delete_attributelist = llvm::make_scope_exit(
118 [&] { DeleteProcThreadAttributeList(startupinfoex.lpAttributeList); });
123 inherited_handles.push_back(
reinterpret_cast<HANDLE
>(act->
GetFD()));
125 if (!inherited_handles.empty()) {
126 if (!UpdateProcThreadAttribute(
127 startupinfoex.lpAttributeList, 0,
128 PROC_THREAD_ATTRIBUTE_HANDLE_LIST, inherited_handles.data(),
129 inherited_handles.size() *
sizeof(HANDLE),
136 const char *hide_console_var =
137 getenv(
"LLDB_LAUNCH_INFERIORS_WITHOUT_CONSOLE");
138 if (hide_console_var &&
139 llvm::StringRef(hide_console_var).equals_insensitive(
"true")) {
140 startupinfo.dwFlags |= STARTF_USESHOWWINDOW;
141 startupinfo.wShowWindow = SW_HIDE;
144 DWORD flags = CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT |
145 EXTENDED_STARTUPINFO_PRESENT;
147 flags |= DEBUG_ONLY_THIS_PROCESS;
149 if (launch_info.
GetFlags().
Test(eLaunchFlagDisableSTDIO))
150 flags &= ~CREATE_NEW_CONSOLE;
152 LPVOID env_block =
nullptr;
154 env_block = environment.data();
157 std::wstring wcommandLine;
160 std::wstring wexecutable, wworkingDirectory;
161 llvm::ConvertUTF8toWide(executable, wexecutable);
167 WCHAR *pwcommandLine = wcommandLine.empty() ? nullptr : &wcommandLine[0];
169 BOOL result = ::CreateProcessW(
170 wexecutable.c_str(), pwcommandLine, NULL, NULL,
171 !inherited_handles.empty(), flags, env_block,
172 wworkingDirectory.size() == 0 ? NULL : wworkingDirectory.c_str(),
173 reinterpret_cast<STARTUPINFO *
>(&startupinfoex), &pi);
185 ::CloseHandle(pi.hThread);
198 if (action ==
nullptr)
200 SECURITY_ATTRIBUTES secattr = {};
201 secattr.nLength =
sizeof(SECURITY_ATTRIBUTES);
202 secattr.bInheritHandle = TRUE;
204 llvm::StringRef path = action->
GetPath();
206 DWORD share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
209 if (fd == STDIN_FILENO) {
210 access = GENERIC_READ;
211 create = OPEN_EXISTING;
212 flags = FILE_ATTRIBUTE_READONLY;
214 if (fd == STDOUT_FILENO || fd == STDERR_FILENO) {
215 access = GENERIC_WRITE;
216 create = CREATE_ALWAYS;
217 if (fd == STDERR_FILENO)
218 flags = FILE_FLAG_WRITE_THROUGH;
222 llvm::ConvertUTF8toWide(path, wpath);
223 HANDLE result = ::CreateFileW(wpath.c_str(), access, share, &secattr, create,
225 return (result == INVALID_HANDLE_VALUE) ? NULL : result;