@@ -201,50 +201,53 @@ func spawnExecutable(
201
201
try inherit ( standardError, as: & startupInfo. pointee. StartupInfo. hStdError)
202
202
startupInfo. pointee. StartupInfo. dwFlags |= STARTF_USESTDHANDLES
203
203
204
- // Forward the back channel's write end to the child process so that it can
205
- // send information back to us. Note that we don't keep the pipe open as
206
- // bidirectional, though we could if we find we need to in the future.
207
- let inheritedHandlesBuffer = UnsafeMutableBufferPointer< HANDLE?> . allocate( capacity: additionalFileHandles. count)
208
- defer {
209
- inheritedHandlesBuffer. deallocate ( )
210
- }
204
+ // Ensure standard I/O streams and any explicitly added file handles are
205
+ // inherited by the child process.
206
+ var inheritedHandles = [ HANDLE? ] ( repeating: nil , count: additionalFileHandles. count + 3 )
207
+ try inherit ( standardInput, as: & inheritedHandles[ 0 ] )
208
+ try inherit ( standardOutput, as: & inheritedHandles[ 1 ] )
209
+ try inherit ( standardError, as: & inheritedHandles[ 2 ] )
211
210
for i in 0 ..< additionalFileHandles. count {
212
- try inherit ( additionalFileHandles [ i] . pointee, as: & inheritedHandlesBuffer [ i ] )
211
+ try inherit ( additionalFileHandles [ i] . pointee, as: & inheritedHandles [ i + 3 ] )
213
212
}
214
- _ = UpdateProcThreadAttribute (
215
- startupInfo. pointee. lpAttributeList,
216
- 0 ,
217
- swt_PROC_THREAD_ATTRIBUTE_HANDLE_LIST ( ) ,
218
- inheritedHandlesBuffer. baseAddress!,
219
- SIZE_T ( MemoryLayout < HANDLE > . stride * inheritedHandlesBuffer. count) ,
220
- nil ,
221
- nil
222
- )
213
+ inheritedHandles = inheritedHandles. compactMap ( \. self)
223
214
224
- let commandLine = _escapeCommandLine ( CollectionOfOne ( executablePath) + arguments)
225
- let environ = environment. map { " \( $0. key) = \( $0. value) " } . joined ( separator: " \0 " ) + " \0 \0 "
215
+ return try inheritedHandles. withUnsafeMutableBufferPointer { inheritedHandles in
216
+ _ = UpdateProcThreadAttribute (
217
+ startupInfo. pointee. lpAttributeList,
218
+ 0 ,
219
+ swt_PROC_THREAD_ATTRIBUTE_HANDLE_LIST ( ) ,
220
+ inheritedHandles. baseAddress!,
221
+ SIZE_T ( MemoryLayout < HANDLE > . stride * inheritedHandles. count) ,
222
+ nil ,
223
+ nil
224
+ )
226
225
227
- return try commandLine. withCString ( encodedAs: UTF16 . self) { commandLine in
228
- try environ. withCString ( encodedAs: UTF16 . self) { environ in
229
- var processInfo = PROCESS_INFORMATION ( )
226
+ let commandLine = _escapeCommandLine ( CollectionOfOne ( executablePath) + arguments)
227
+ let environ = environment. map { " \( $0. key) = \( $0. value) " } . joined ( separator: " \0 " ) + " \0 \0 "
230
228
231
- guard CreateProcessW (
232
- nil ,
233
- . init( mutating: commandLine) ,
234
- nil ,
235
- nil ,
236
- true , // bInheritHandles
237
- DWORD ( CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT | EXTENDED_STARTUPINFO_PRESENT) ,
238
- . init( mutating: environ) ,
239
- nil ,
240
- startupInfo. pointer ( to: \. StartupInfo) !,
241
- & processInfo
242
- ) else {
243
- throw Win32Error ( rawValue: GetLastError ( ) )
244
- }
245
- _ = CloseHandle ( processInfo. hThread)
229
+ return try commandLine. withCString ( encodedAs: UTF16 . self) { commandLine in
230
+ try environ. withCString ( encodedAs: UTF16 . self) { environ in
231
+ var processInfo = PROCESS_INFORMATION ( )
246
232
247
- return processInfo. hProcess!
233
+ guard CreateProcessW (
234
+ nil ,
235
+ . init( mutating: commandLine) ,
236
+ nil ,
237
+ nil ,
238
+ true , // bInheritHandles
239
+ DWORD ( CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT | EXTENDED_STARTUPINFO_PRESENT) ,
240
+ . init( mutating: environ) ,
241
+ nil ,
242
+ startupInfo. pointer ( to: \. StartupInfo) !,
243
+ & processInfo
244
+ ) else {
245
+ throw Win32Error ( rawValue: GetLastError ( ) )
246
+ }
247
+ _ = CloseHandle ( processInfo. hThread)
248
+
249
+ return processInfo. hProcess!
250
+ }
248
251
}
249
252
}
250
253
}
0 commit comments