@@ -976,6 +976,46 @@ internal typealias PlatformFileDescriptor = HANDLE
976
976
977
977
// MARK: - Pipe Support
978
978
extension FileDescriptor {
979
+ // NOTE: Not the same as SwiftSystem's FileDescriptor.pipe, which has different behavior,
980
+ // because it passes _O_NOINHERIT through the _pipe interface (https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/pipe),
981
+ // which ends up setting bInheritHandle to false in the SECURITY_ATTRIBUTES (see ucrt/conio/pipe.cpp in the ucrt sources).
982
+ internal static func ssp_pipe( ) throws -> (
983
+ readEnd: FileDescriptor ,
984
+ writeEnd: FileDescriptor
985
+ ) {
986
+ var saAttributes : SECURITY_ATTRIBUTES = SECURITY_ATTRIBUTES ( )
987
+ saAttributes. nLength = DWORD ( MemoryLayout< SECURITY_ATTRIBUTES> . size)
988
+ saAttributes. bInheritHandle = true
989
+ saAttributes. lpSecurityDescriptor = nil
990
+
991
+ var readHandle : HANDLE ? = nil
992
+ var writeHandle : HANDLE ? = nil
993
+ guard CreatePipe ( & readHandle, & writeHandle, & saAttributes, 0 ) ,
994
+ readHandle != INVALID_HANDLE_VALUE,
995
+ writeHandle != INVALID_HANDLE_VALUE,
996
+ let readHandle: HANDLE = readHandle,
997
+ let writeHandle: HANDLE = writeHandle
998
+ else {
999
+ throw SubprocessError (
1000
+ code: . init( . failedToCreatePipe) ,
1001
+ underlyingError: . init( rawValue: GetLastError ( ) )
1002
+ )
1003
+ }
1004
+ let readFd = _open_osfhandle (
1005
+ intptr_t ( bitPattern: readHandle) ,
1006
+ FileDescriptor . AccessMode. readOnly. rawValue
1007
+ )
1008
+ let writeFd = _open_osfhandle (
1009
+ intptr_t ( bitPattern: writeHandle) ,
1010
+ FileDescriptor . AccessMode. writeOnly. rawValue
1011
+ )
1012
+
1013
+ return (
1014
+ readEnd: FileDescriptor ( rawValue: readFd) ,
1015
+ writeEnd: FileDescriptor ( rawValue: writeFd)
1016
+ )
1017
+ }
1018
+
979
1019
var platformDescriptor : PlatformFileDescriptor {
980
1020
return HANDLE ( bitPattern: _get_osfhandle ( self . rawValue) ) !
981
1021
}
0 commit comments