@@ -447,9 +447,10 @@ private extension Process {
447
447
self . environment = environment
448
448
}
449
449
450
- let outputPipe = Pipe ( ) , errorPipe = Pipe ( )
451
- self . standardOutput = outputPipe
452
- self . standardError = errorPipe
450
+ let outputPipe = SocketPair ( )
451
+ let errorPipe = SocketPair ( )
452
+ self . standardOutput = outputPipe. fileHandleForWriting
453
+ self . standardError = errorPipe. fileHandleForWriting
453
454
454
455
// Because FileHandle's readabilityHandler might be called from a
455
456
// different queue from the calling queue, avoid data races by
@@ -646,3 +647,30 @@ private extension String {
646
647
self = appending ( arguments: arguments)
647
648
}
648
649
}
650
+
651
+
652
+ final class SocketPair {
653
+ let fileHandleForReading : FileHandle
654
+ let fileHandleForWriting : FileHandle
655
+
656
+ init ( ) {
657
+ let fds = UnsafeMutablePointer< Int32> . allocate( capacity: 2 )
658
+ defer { fds. deallocate ( ) }
659
+
660
+ #if os(macOS)
661
+ let ret = socketpair ( AF_UNIX, SOCK_STREAM, 0 , fds)
662
+ #else
663
+ let ret = socketpair ( AF_UNIX, Int32 ( SOCK_STREAM . rawValue) , 0 , fds)
664
+ #endif
665
+ switch ( ret, errno) {
666
+ case ( 0 , _) :
667
+ self . fileHandleForReading = FileHandle ( fileDescriptor: fds. pointee, closeOnDealloc: true )
668
+ self . fileHandleForWriting = FileHandle ( fileDescriptor: fds. successor ( ) . pointee, closeOnDealloc: true )
669
+ case ( - 1 , EMFILE) , ( - 1 , ENFILE) :
670
+ self . fileHandleForReading = FileHandle ( fileDescriptor: - 1 , closeOnDealloc: false )
671
+ self . fileHandleForWriting = FileHandle ( fileDescriptor: - 1 , closeOnDealloc: false )
672
+ default :
673
+ fatalError ( " Error calling socketpair(): \( errno) " )
674
+ }
675
+ }
676
+ }
0 commit comments