@@ -90,9 +90,6 @@ public struct Configuration: Sendable {
90
90
// After spawn, cleanup child side fds
91
91
try await self . cleanup (
92
92
execution: execution,
93
- inputPipe: inputPipe,
94
- outputPipe: outputPipe,
95
- errorPipe: errorPipe,
96
93
childSide: true ,
97
94
parentSide: false ,
98
95
attemptToTerminateSubProcess: false
@@ -104,7 +101,7 @@ public struct Configuration: Sendable {
104
101
// Body runs in the same isolation
105
102
let result = try await body (
106
103
execution,
107
- . init( fileDescriptor: inputPipe. writeFileDescriptor!)
104
+ . init( fileDescriptor: execution . inputPipe. writeFileDescriptor!)
108
105
)
109
106
return ExecutionResult (
110
107
terminationStatus: try await waitingStatus,
@@ -116,9 +113,6 @@ public struct Configuration: Sendable {
116
113
// this is the best we can do
117
114
try ? await self . cleanup (
118
115
execution: execution,
119
- inputPipe: inputPipe,
120
- outputPipe: outputPipe,
121
- errorPipe: errorPipe,
122
116
childSide: false ,
123
117
parentSide: true ,
124
118
attemptToTerminateSubProcess: true
@@ -154,9 +148,6 @@ public struct Configuration: Sendable {
154
148
// After spawn, clean up child side
155
149
try await self . cleanup (
156
150
execution: execution,
157
- inputPipe: inputPipe,
158
- outputPipe: outputPipe,
159
- errorPipe: errorPipe,
160
151
childSide: true ,
161
152
parentSide: false ,
162
153
attemptToTerminateSubProcess: false
@@ -174,7 +165,7 @@ public struct Configuration: Sendable {
174
165
standardError
175
166
) = try await execution. captureIOs ( )
176
167
// Write input in the same scope
177
- guard let writeFd = inputPipe. writeFileDescriptor else {
168
+ guard let writeFd = execution . inputPipe. writeFileDescriptor else {
178
169
fatalError ( " Trying to write to an input that has been closed " )
179
170
}
180
171
try await withCheckedThrowingContinuation { ( continuation: CheckedContinuation < Void , any Swift . Error > ) in
@@ -193,7 +184,7 @@ public struct Configuration: Sendable {
193
184
)
194
185
#endif
195
186
196
- writeFd. wrapped . write ( bytes) { _, error in
187
+ writeFd. write ( bytes) { _, error in
197
188
if let error = error {
198
189
continuation. resume ( throwing: error)
199
190
} else {
@@ -216,9 +207,6 @@ public struct Configuration: Sendable {
216
207
// this is the best we can do
217
208
try ? await self . cleanup (
218
209
execution: execution,
219
- inputPipe: inputPipe,
220
- outputPipe: outputPipe,
221
- errorPipe: errorPipe,
222
210
childSide: false ,
223
211
parentSide: true ,
224
212
attemptToTerminateSubProcess: true
@@ -257,9 +245,6 @@ public struct Configuration: Sendable {
257
245
// After spawn, clean up child side
258
246
try await self . cleanup (
259
247
execution: execution,
260
- inputPipe: inputPipe,
261
- outputPipe: outputPipe,
262
- errorPipe: errorPipe,
263
248
childSide: true ,
264
249
parentSide: false ,
265
250
attemptToTerminateSubProcess: false
@@ -271,7 +256,7 @@ public struct Configuration: Sendable {
271
256
returning: ExecutionResult . self
272
257
) { group in
273
258
group. addTask {
274
- if let writeFd = inputPipe. writeFileDescriptor {
259
+ if let writeFd = execution . inputPipe. writeFileDescriptor {
275
260
let writer = StandardInputWriter ( fileDescriptor: writeFd)
276
261
try await input. write ( with: writer)
277
262
try await writer. finish ( )
@@ -300,9 +285,6 @@ public struct Configuration: Sendable {
300
285
// this is the best we can do
301
286
try ? await self . cleanup (
302
287
execution: execution,
303
- inputPipe: inputPipe,
304
- outputPipe: outputPipe,
305
- errorPipe: errorPipe,
306
288
childSide: false ,
307
289
parentSide: true ,
308
290
attemptToTerminateSubProcess: true
@@ -350,9 +332,6 @@ extension Configuration {
350
332
Error: OutputProtocol
351
333
> (
352
334
execution: Execution < Output , Error > ,
353
- inputPipe: CreatedPipe ,
354
- outputPipe: CreatedPipe ,
355
- errorPipe: CreatedPipe ,
356
335
childSide: Bool ,
357
336
parentSide: Bool ,
358
337
attemptToTerminateSubProcess: Bool
@@ -384,25 +363,25 @@ extension Configuration {
384
363
385
364
if childSide {
386
365
inputError = captureError {
387
- try inputPipe. readFileDescriptor? . safelyClose ( )
366
+ try execution . inputPipe. readFileDescriptor? . safelyClose ( )
388
367
}
389
368
outputError = captureError {
390
- try outputPipe. writeFileDescriptor? . safelyClose ( )
369
+ try execution . outputPipe. writeFileDescriptor? . safelyClose ( )
391
370
}
392
371
errorError = captureError {
393
- try errorPipe. writeFileDescriptor? . safelyClose ( )
372
+ try execution . errorPipe. writeFileDescriptor? . safelyClose ( )
394
373
}
395
374
}
396
375
397
376
if parentSide {
398
377
inputError = captureError {
399
- try inputPipe. writeFileDescriptor? . safelyClose ( )
378
+ try execution . inputPipe. writeFileDescriptor? . safelyClose ( )
400
379
}
401
380
outputError = captureError {
402
- try outputPipe. readFileDescriptor? . safelyClose ( )
381
+ try execution . outputPipe. readFileDescriptor? . safelyClose ( )
403
382
}
404
383
errorError = captureError {
405
- try errorPipe. readFileDescriptor? . safelyClose ( )
384
+ try execution . errorPipe. readFileDescriptor? . safelyClose ( )
406
385
}
407
386
}
408
387
@@ -822,27 +801,51 @@ internal enum StringOrRawBytes: Sendable, Hashable {
822
801
}
823
802
}
824
803
825
- /// A simple wrapper on `FileDescriptor` plus a flag indicating
826
- /// whether it should be closed automactially when done.
827
- internal struct TrackedFileDescriptor : Hashable {
804
+ /// A wrapped `FileDescriptor` or `DispatchIO` and
805
+ /// whether it should beeddsw closed automactially when done.
806
+ internal struct DiskIO {
807
+ internal enum Storage {
808
+ case fileDescriptor( FileDescriptor )
809
+ #if !os(Windows) // Darwin and Linux
810
+ case dispatchIO( DispatchIO )
811
+ #endif
812
+ }
813
+
828
814
internal let closeWhenDone : Bool
829
- internal let wrapped : FileDescriptor
815
+ internal let storage : Storage
830
816
831
817
internal init (
832
- _ wrapped : FileDescriptor ,
818
+ _ fileDescriptor : FileDescriptor ,
833
819
closeWhenDone: Bool
834
820
) {
835
- self . wrapped = wrapped
821
+ self . storage = . fileDescriptor ( fileDescriptor )
836
822
self . closeWhenDone = closeWhenDone
837
823
}
838
824
825
+ #if !os(Windows)
826
+ internal init (
827
+ _ dispatchIO: DispatchIO ,
828
+ closeWhenDone: Bool
829
+ ) {
830
+ self . storage = . dispatchIO( dispatchIO)
831
+ self . closeWhenDone = closeWhenDone
832
+ }
833
+ #endif
834
+
839
835
internal func safelyClose( ) throws {
840
836
guard self . closeWhenDone else {
841
837
return
842
838
}
843
839
844
840
do {
845
- try self . wrapped. close ( )
841
+ switch self . storage {
842
+ case . fileDescriptor( let fileDescriptor) :
843
+ try fileDescriptor. close ( )
844
+ #if !os(Windows)
845
+ case . dispatchIO( let dispatchIO) :
846
+ dispatchIO. close ( )
847
+ #endif
848
+ }
846
849
} catch {
847
850
guard let errno: Errno = error as? Errno else {
848
851
throw error
@@ -854,25 +857,39 @@ internal struct TrackedFileDescriptor: Hashable {
854
857
}
855
858
856
859
internal var platformDescriptor : PlatformFileDescriptor {
857
- return self . wrapped. platformDescriptor
860
+ switch self . storage {
861
+ case . fileDescriptor( let fileDescriptor) :
862
+ return fileDescriptor. platformDescriptor
863
+ #if !os(Windows)
864
+ case . dispatchIO( let dispatchIO) :
865
+ return dispatchIO. fileDescriptor
866
+ #endif // !os(Windows)
867
+ }
858
868
}
859
869
}
860
870
861
871
internal struct CreatedPipe {
862
- internal let readFileDescriptor : TrackedFileDescriptor ?
863
- internal let writeFileDescriptor : TrackedFileDescriptor ?
872
+ internal enum PipeEnd {
873
+ case readEnd
874
+ case writeEnd
875
+ }
876
+
877
+ internal let readFileDescriptor : DiskIO ?
878
+ internal let writeFileDescriptor : DiskIO ?
879
+ internal let parentEnd : PipeEnd
864
880
865
881
internal init (
866
- readFileDescriptor: TrackedFileDescriptor ? ,
867
- writeFileDescriptor: TrackedFileDescriptor ?
882
+ readFileDescriptor: DiskIO ? ,
883
+ writeFileDescriptor: DiskIO ? ,
884
+ parentEnd: PipeEnd
868
885
) {
869
886
self . readFileDescriptor = readFileDescriptor
870
887
self . writeFileDescriptor = writeFileDescriptor
888
+ self . parentEnd = parentEnd
871
889
}
872
890
873
- internal init ( closeWhenDone: Bool ) throws {
891
+ internal init ( closeWhenDone: Bool , parentEnd : PipeEnd ) throws {
874
892
let pipe = try FileDescriptor . ssp_pipe ( )
875
-
876
893
self . readFileDescriptor = . init(
877
894
pipe. readEnd,
878
895
closeWhenDone: closeWhenDone
@@ -881,6 +898,7 @@ internal struct CreatedPipe {
881
898
pipe. writeEnd,
882
899
closeWhenDone: closeWhenDone
883
900
)
901
+ self . parentEnd = parentEnd
884
902
}
885
903
}
886
904
0 commit comments