@@ -85,6 +85,10 @@ extension Process {
8585 let stdoutPipe = Pipe ( )
8686 let stderrPipe = Pipe ( )
8787
88+ // Extend the lifetime of the pipes to avoid file descriptors being closed until the AsyncStream is finished being consumed.
89+ defer { withExtendedLifetime ( stdoutPipe) { } }
90+ defer { withExtendedLifetime ( stderrPipe) { } }
91+
8892 let ( exitStatus, output) = try await _getOutput ( url: url, arguments: arguments, currentDirectoryURL: currentDirectoryURL, environment: environment, interruptible: interruptible) { process in
8993 let stdoutStream = process. makeStream ( for: \. standardOutputPipe, using: stdoutPipe)
9094 let stderrStream = process. makeStream ( for: \. standardErrorPipe, using: stderrPipe)
@@ -99,6 +103,10 @@ extension Process {
99103 let stdoutPipe = Pipe ( )
100104 let stderrPipe = Pipe ( )
101105
106+ // Extend the lifetime of the pipes to avoid file descriptors being closed until the AsyncStream is finished being consumed.
107+ defer { withExtendedLifetime ( stdoutPipe) { } }
108+ defer { withExtendedLifetime ( stderrPipe) { } }
109+
102110 let ( exitStatus, output) = try await _getOutput ( url: url, arguments: arguments, currentDirectoryURL: currentDirectoryURL, environment: environment, interruptible: interruptible) { process in
103111 let stdoutStream = process. _makeStream ( for: \. standardOutputPipe, using: stdoutPipe)
104112 let stderrStream = process. _makeStream ( for: \. standardErrorPipe, using: stderrPipe)
@@ -116,6 +124,9 @@ extension Process {
116124 if #available( macOS 15 , iOS 18 , tvOS 18 , watchOS 11 , visionOS 2 , * ) {
117125 let pipe = Pipe ( )
118126
127+ // Extend the lifetime of the pipes to avoid file descriptors being closed until the AsyncStream is finished being consumed.
128+ defer { withExtendedLifetime ( pipe) { } }
129+
119130 let ( exitStatus, output) = try await _getOutput ( url: url, arguments: arguments, currentDirectoryURL: currentDirectoryURL, environment: environment, interruptible: interruptible) { process in
120131 process. standardOutputPipe = pipe
121132 process. standardErrorPipe = pipe
@@ -127,6 +138,9 @@ extension Process {
127138 } else {
128139 let pipe = Pipe ( )
129140
141+ // Extend the lifetime of the pipes to avoid file descriptors being closed until the AsyncStream is finished being consumed.
142+ defer { withExtendedLifetime ( pipe) { } }
143+
130144 let ( exitStatus, output) = try await _getOutput ( url: url, arguments: arguments, currentDirectoryURL: currentDirectoryURL, environment: environment, interruptible: interruptible) { process in
131145 process. standardOutputPipe = pipe
132146 process. standardErrorPipe = pipe
0 commit comments