Skip to content

Commit e3b2e09

Browse files
committed
Fix Pipe Inheritance on Windows
- The Security Attributes should allow handle inheritance - The Startup info should indicate the child should use the passed in pipes for stdin/stdout/stderr - The write end of stdin and read end of stdout/stderr shouldn't be inherited by the child
1 parent bbfd56e commit e3b2e09

File tree

2 files changed

+11
-1
lines changed

2 files changed

+11
-1
lines changed

Foundation/FileHandle.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -975,9 +975,15 @@ open class Pipe: NSObject {
975975

976976
public override init() {
977977
#if os(Windows)
978+
var saAttr = SECURITY_ATTRIBUTES()
979+
saAttr.nLength = DWORD(MemoryLayout<SECURITY_ATTRIBUTES>.size)
980+
saAttr.bInheritHandle = true
981+
saAttr.lpSecurityDescriptor = nil
982+
978983
var hReadPipe: HANDLE?
979984
var hWritePipe: HANDLE?
980-
if !CreatePipe(&hReadPipe, &hWritePipe, nil, 0) {
985+
986+
if !CreatePipe(&hReadPipe, &hWritePipe, &saAttr, 0) {
981987
fatalError("CreatePipe failed")
982988
}
983989
self.fileHandleForReading = FileHandle(handle: hReadPipe!,

Foundation/Process.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ open class Process: NSObject {
386386

387387
var siStartupInfo: STARTUPINFOW = STARTUPINFOW()
388388
siStartupInfo.cb = DWORD(MemoryLayout<STARTUPINFOW>.size)
389+
siStartupInfo.dwFlags = DWORD(STARTF_USESTDHANDLES)
389390

390391
var _devNull: FileHandle?
391392
func devNullFd() throws -> HANDLE {
@@ -396,6 +397,7 @@ open class Process: NSObject {
396397
switch standardInput {
397398
case let pipe as Pipe:
398399
siStartupInfo.hStdInput = pipe.fileHandleForReading.handle
400+
SetHandleInformation(pipe.fileHandleForWriting.handle, DWORD(HANDLE_FLAG_INHERIT), 0)
399401

400402
// nil or NullDevice maps to NUL
401403
case let handle as FileHandle where handle === FileHandle._nulldeviceFileHandle: fallthrough
@@ -410,6 +412,7 @@ open class Process: NSObject {
410412
switch standardOutput {
411413
case let pipe as Pipe:
412414
siStartupInfo.hStdOutput = pipe.fileHandleForWriting.handle
415+
SetHandleInformation(pipe.fileHandleForReading.handle, DWORD(HANDLE_FLAG_INHERIT), 0)
413416

414417
// nil or NullDevice maps to NUL
415418
case let handle as FileHandle where handle === FileHandle._nulldeviceFileHandle: fallthrough
@@ -424,6 +427,7 @@ open class Process: NSObject {
424427
switch standardError {
425428
case let pipe as Pipe:
426429
siStartupInfo.hStdError = pipe.fileHandleForWriting.handle
430+
SetHandleInformation(pipe.fileHandleForReading.handle, DWORD(HANDLE_FLAG_INHERIT), 0)
427431

428432
// nil or NullDevice maps to NUL
429433
case let handle as FileHandle where handle === FileHandle._nulldeviceFileHandle: fallthrough

0 commit comments

Comments
 (0)