@@ -90,9 +90,6 @@ public struct Configuration: Sendable {
9090        // After spawn, cleanup child side fds
9191        try   await  self . cleanup ( 
9292            execution:  execution, 
93-             inputPipe:  inputPipe, 
94-             outputPipe:  outputPipe, 
95-             errorPipe:  errorPipe, 
9693            childSide:  true , 
9794            parentSide:  false , 
9895            attemptToTerminateSubProcess:  false 
@@ -104,7 +101,7 @@ public struct Configuration: Sendable {
104101            // Body runs in the same isolation
105102            let  result  =  try   await  body ( 
106103                execution, 
107-                 . init( fileDescriptor:  inputPipe. writeFileDescriptor!) 
104+                 . init( fileDescriptor:  execution . inputPipe. writeFileDescriptor!) 
108105            ) 
109106            return  ExecutionResult ( 
110107                terminationStatus:  try   await  waitingStatus, 
@@ -116,9 +113,6 @@ public struct Configuration: Sendable {
116113            // this is the best we can do
117114            try ?   await  self . cleanup ( 
118115                execution:  execution, 
119-                 inputPipe:  inputPipe, 
120-                 outputPipe:  outputPipe, 
121-                 errorPipe:  errorPipe, 
122116                childSide:  false , 
123117                parentSide:  true , 
124118                attemptToTerminateSubProcess:  true 
@@ -154,9 +148,6 @@ public struct Configuration: Sendable {
154148        // After spawn, clean up child side
155149        try   await  self . cleanup ( 
156150            execution:  execution, 
157-             inputPipe:  inputPipe, 
158-             outputPipe:  outputPipe, 
159-             errorPipe:  errorPipe, 
160151            childSide:  true , 
161152            parentSide:  false , 
162153            attemptToTerminateSubProcess:  false 
@@ -174,7 +165,7 @@ public struct Configuration: Sendable {
174165                standardError
175166            )  =  try   await  execution. captureIOs ( ) 
176167            // Write input in the same scope
177-             guard  let  writeFd =  inputPipe. writeFileDescriptor else  { 
168+             guard  let  writeFd =  execution . inputPipe. writeFileDescriptor else  { 
178169                fatalError ( " Trying to write to an input that has been closed " ) 
179170            } 
180171            try   await  withCheckedThrowingContinuation  {  ( continuation:  CheckedContinuation < Void ,  any  Swift . Error > )  in 
@@ -193,7 +184,7 @@ public struct Configuration: Sendable {
193184                    ) 
194185                    #endif 
195186
196-                     writeFd. wrapped . write ( bytes)  {  _,  error in 
187+                     writeFd. write ( bytes)  {  _,  error in 
197188                        if  let  error =  error { 
198189                            continuation. resume ( throwing:  error) 
199190                        }  else  { 
@@ -216,9 +207,6 @@ public struct Configuration: Sendable {
216207            // this is the best we can do
217208            try ?   await  self . cleanup ( 
218209                execution:  execution, 
219-                 inputPipe:  inputPipe, 
220-                 outputPipe:  outputPipe, 
221-                 errorPipe:  errorPipe, 
222210                childSide:  false , 
223211                parentSide:  true , 
224212                attemptToTerminateSubProcess:  true 
@@ -257,9 +245,6 @@ public struct Configuration: Sendable {
257245        // After spawn, clean up child side
258246        try   await  self . cleanup ( 
259247            execution:  execution, 
260-             inputPipe:  inputPipe, 
261-             outputPipe:  outputPipe, 
262-             errorPipe:  errorPipe, 
263248            childSide:  true , 
264249            parentSide:  false , 
265250            attemptToTerminateSubProcess:  false 
@@ -271,7 +256,7 @@ public struct Configuration: Sendable {
271256                returning:  ExecutionResult . self
272257            )  {  group in 
273258                group. addTask  { 
274-                     if  let  writeFd =  inputPipe. writeFileDescriptor { 
259+                     if  let  writeFd =  execution . inputPipe. writeFileDescriptor { 
275260                        let  writer  =  StandardInputWriter ( fileDescriptor:  writeFd) 
276261                        try   await  input. write ( with:  writer) 
277262                        try   await  writer. finish ( ) 
@@ -300,9 +285,6 @@ public struct Configuration: Sendable {
300285            // this is the best we can do
301286            try ?   await  self . cleanup ( 
302287                execution:  execution, 
303-                 inputPipe:  inputPipe, 
304-                 outputPipe:  outputPipe, 
305-                 errorPipe:  errorPipe, 
306288                childSide:  false , 
307289                parentSide:  true , 
308290                attemptToTerminateSubProcess:  true 
@@ -350,9 +332,6 @@ extension Configuration {
350332        Error:  OutputProtocol 
351333    > ( 
352334        execution:  Execution < Output ,  Error > , 
353-         inputPipe:  CreatedPipe , 
354-         outputPipe:  CreatedPipe , 
355-         errorPipe:  CreatedPipe , 
356335        childSide:  Bool , 
357336        parentSide:  Bool , 
358337        attemptToTerminateSubProcess:  Bool 
@@ -384,25 +363,25 @@ extension Configuration {
384363
385364        if  childSide { 
386365            inputError =  captureError  { 
387-                 try   inputPipe. readFileDescriptor? . safelyClose ( ) 
366+                 try   execution . inputPipe. readFileDescriptor? . safelyClose ( ) 
388367            } 
389368            outputError =  captureError  { 
390-                 try   outputPipe. writeFileDescriptor? . safelyClose ( ) 
369+                 try   execution . outputPipe. writeFileDescriptor? . safelyClose ( ) 
391370            } 
392371            errorError =  captureError  { 
393-                 try   errorPipe. writeFileDescriptor? . safelyClose ( ) 
372+                 try   execution . errorPipe. writeFileDescriptor? . safelyClose ( ) 
394373            } 
395374        } 
396375
397376        if  parentSide { 
398377            inputError =  captureError  { 
399-                 try   inputPipe. writeFileDescriptor? . safelyClose ( ) 
378+                 try   execution . inputPipe. writeFileDescriptor? . safelyClose ( ) 
400379            } 
401380            outputError =  captureError  { 
402-                 try   outputPipe. readFileDescriptor? . safelyClose ( ) 
381+                 try   execution . outputPipe. readFileDescriptor? . safelyClose ( ) 
403382            } 
404383            errorError =  captureError  { 
405-                 try   errorPipe. readFileDescriptor? . safelyClose ( ) 
384+                 try   execution . errorPipe. readFileDescriptor? . safelyClose ( ) 
406385            } 
407386        } 
408387
@@ -822,27 +801,51 @@ internal enum StringOrRawBytes: Sendable, Hashable {
822801    } 
823802} 
824803
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+ 
828814    internal  let  closeWhenDone :  Bool 
829-     internal  let  wrapped :   FileDescriptor 
815+     internal  let  storage :   Storage 
830816
831817    internal  init ( 
832-         _ wrapped :  FileDescriptor , 
818+         _ fileDescriptor :  FileDescriptor , 
833819        closeWhenDone:  Bool 
834820    )  { 
835-         self . wrapped  =  wrapped 
821+         self . storage  =  . fileDescriptor ( fileDescriptor ) 
836822        self . closeWhenDone =  closeWhenDone
837823    } 
838824
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+ 
839835    internal  func  safelyClose( )  throws  { 
840836        guard  self . closeWhenDone else  { 
841837            return 
842838        } 
843839
844840        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+             } 
846849        }  catch  { 
847850            guard  let  errno:  Errno  =  error as?  Errno  else  { 
848851                throw  error
@@ -854,25 +857,39 @@ internal struct TrackedFileDescriptor: Hashable {
854857    } 
855858
856859    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+         } 
858868    } 
859869} 
860870
861871internal 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 
864880
865881    internal  init ( 
866-         readFileDescriptor:  TrackedFileDescriptor ? , 
867-         writeFileDescriptor:  TrackedFileDescriptor ? 
882+         readFileDescriptor:  DiskIO ? , 
883+         writeFileDescriptor:  DiskIO ? , 
884+         parentEnd:  PipeEnd 
868885    )  { 
869886        self . readFileDescriptor =  readFileDescriptor
870887        self . writeFileDescriptor =  writeFileDescriptor
888+         self . parentEnd =  parentEnd
871889    } 
872890
873-     internal  init ( closeWhenDone:  Bool )  throws  { 
891+     internal  init ( closeWhenDone:  Bool ,  parentEnd :   PipeEnd )  throws  { 
874892        let  pipe  =  try   FileDescriptor . ssp_pipe ( ) 
875- 
876893        self . readFileDescriptor =  . init( 
877894            pipe. readEnd, 
878895            closeWhenDone:  closeWhenDone
@@ -881,6 +898,7 @@ internal struct CreatedPipe {
881898            pipe. writeEnd, 
882899            closeWhenDone:  closeWhenDone
883900        ) 
901+         self . parentEnd =  parentEnd
884902    } 
885903} 
886904
0 commit comments