@@ -79,38 +79,42 @@ public struct Configuration: Sendable {
79
79
80
80
let execution = _spawnResult. execution
81
81
82
- let result : Swift . Result < Result , Error >
83
- do {
84
- result = try await . success( withAsyncTaskCleanupHandler {
85
- let inputIO = _spawnResult. inputWriteEnd ( )
86
- let outputIO = _spawnResult. outputReadEnd ( )
87
- let errorIO = _spawnResult. errorReadEnd ( )
82
+ return try await withAsyncTaskCleanupHandler {
83
+ let inputIO = _spawnResult. inputWriteEnd ( )
84
+ let outputIO = _spawnResult. outputReadEnd ( )
85
+ let errorIO = _spawnResult. errorReadEnd ( )
88
86
87
+ let result : Swift . Result < Result , Error >
88
+ do {
89
89
// Body runs in the same isolation
90
- return try await body ( _spawnResult. execution, inputIO, outputIO, errorIO)
91
- } onCleanup: {
92
- // Attempt to terminate the child process
93
- await execution. runTeardownSequence (
94
- self . platformOptions. teardownSequence
95
- )
96
- } )
97
- } catch {
98
- result = . failure( error)
99
- }
90
+ let bodyResult = try await body ( _spawnResult. execution, inputIO, outputIO, errorIO)
91
+ result = . success( bodyResult)
92
+ } catch {
93
+ result = . failure( error)
94
+ }
100
95
101
- // Ensure that we begin monitoring process termination after `body` runs
102
- // and regardless of whether `body` throws, so that the pid gets reaped
103
- // even if `body` throws, and we are not leaving zombie processes in the
104
- // process table which will cause the process termination monitoring thread
105
- // to effectively hang due to the pid never being awaited
106
- let terminationStatus = try await Subprocess . monitorProcessTermination (
107
- for: execution. processIdentifier
108
- )
96
+ // Ensure that we begin monitoring process termination after `body` runs
97
+ // and regardless of whether `body` throws, so that the pid gets reaped
98
+ // even if `body` throws, and we are not leaving zombie processes in the
99
+ // process table which will cause the process termination monitoring thread
100
+ // to effectively hang due to the pid never being awaited
101
+ let terminationStatus = try await monitorProcessTermination (
102
+ for: execution. processIdentifier
103
+ )
109
104
110
- // Close process file descriptor now we finished monitoring
111
- execution. processIdentifier. close ( )
105
+ // Close process file descriptor now we finished monitoring
106
+ execution. processIdentifier. close ( )
112
107
113
- return try ExecutionResult ( terminationStatus: terminationStatus, value: result. get ( ) )
108
+ return ExecutionResult (
109
+ terminationStatus: terminationStatus,
110
+ value: try result. get ( )
111
+ )
112
+ } onCleanup: {
113
+ // Attempt to terminate the child process
114
+ await execution. runTeardownSequence (
115
+ self . platformOptions. teardownSequence
116
+ )
117
+ }
114
118
}
115
119
}
116
120
@@ -246,40 +250,6 @@ extension Executable: CustomStringConvertible, CustomDebugStringConvertible {
246
250
}
247
251
}
248
252
249
- extension Executable {
250
- internal func possibleExecutablePaths(
251
- withPathValue pathValue: String ?
252
- ) -> Set < String > {
253
- switch self . storage {
254
- case . executable( let executableName) :
255
- #if os(Windows)
256
- // Windows CreateProcessW accepts executable name directly
257
- return Set ( [ executableName] )
258
- #else
259
- var results : Set < String > = [ ]
260
- // executableName could be a full path
261
- results. insert ( executableName)
262
- // Get $PATH from environment
263
- let searchPaths : Set < String >
264
- if let pathValue = pathValue {
265
- let localSearchPaths = pathValue. split ( separator: " : " ) . map { String ( $0) }
266
- searchPaths = Set ( localSearchPaths) . union ( Self . defaultSearchPaths)
267
- } else {
268
- searchPaths = Self . defaultSearchPaths
269
- }
270
- for path in searchPaths {
271
- results. insert (
272
- FilePath ( path) . appending ( executableName) . string
273
- )
274
- }
275
- return results
276
- #endif
277
- case . path( let executablePath) :
278
- return Set ( [ executablePath. string] )
279
- }
280
- }
281
- }
282
-
283
253
// MARK: - Arguments
284
254
285
255
/// A collection of arguments to pass to the subprocess.
@@ -300,7 +270,6 @@ public struct Arguments: Sendable, ExpressibleByArrayLiteral, Hashable {
300
270
self . executablePathOverride = nil
301
271
}
302
272
303
- #if !os(Windows) // Windows does NOT support arg0 override
304
273
/// Create an `Argument` object using the given values, but
305
274
/// override the first Argument value to `executablePathOverride`.
306
275
/// If `executablePathOverride` is nil,
@@ -317,7 +286,7 @@ public struct Arguments: Sendable, ExpressibleByArrayLiteral, Hashable {
317
286
self . executablePathOverride = nil
318
287
}
319
288
}
320
-
289
+ #if !os(Windows) // Windows does not support non-unicode arguments
321
290
/// Create an `Argument` object using the given values, but
322
291
/// override the first Argument value to `executablePathOverride`.
323
292
/// If `executablePathOverride` is nil,
@@ -869,7 +838,7 @@ internal struct CreatedPipe: ~Copyable {
869
838
DWORD ( readBufferSize) ,
870
839
DWORD ( readBufferSize) ,
871
840
0 ,
872
- & saAttributes
841
+ nil
873
842
)
874
843
}
875
844
guard let parentEnd, parentEnd != INVALID_HANDLE_VALUE else {
@@ -1029,3 +998,39 @@ internal func withAsyncTaskCleanupHandler<Result>(
1029
998
}
1030
999
}
1031
1000
}
1001
+
1002
+ internal struct _OrderedSet < Element: Hashable & Sendable > : Hashable , Sendable {
1003
+ private var elements : [ Element ]
1004
+ private var hashValueSet : Set < Int >
1005
+
1006
+ internal init ( ) {
1007
+ self . elements = [ ]
1008
+ self . hashValueSet = Set ( )
1009
+ }
1010
+
1011
+ internal init ( _ arrayValue: [ Element ] ) {
1012
+ self . elements = [ ]
1013
+ self . hashValueSet = Set ( )
1014
+
1015
+ for element in arrayValue {
1016
+ self . insert ( element)
1017
+ }
1018
+ }
1019
+
1020
+ mutating func insert( _ element: Element ) {
1021
+ guard !self . hashValueSet. contains ( element. hashValue) else {
1022
+ return
1023
+ }
1024
+ self . elements. append ( element)
1025
+ self . hashValueSet. insert ( element. hashValue)
1026
+ }
1027
+ }
1028
+
1029
+ extension _OrderedSet : Sequence {
1030
+ typealias Iterator = Array < Element > . Iterator
1031
+
1032
+ internal func makeIterator( ) -> Iterator {
1033
+ return self . elements. makeIterator ( )
1034
+ }
1035
+ }
1036
+
0 commit comments