@@ -498,27 +498,6 @@ public struct TTYCommandRunner {
498498 }
499499 }
500500
501- static func drainReadResult( for data: Data , terminalRead: Int , errno err: Int32 ) -> DrainReadResult {
502- if !data. isEmpty {
503- return . data( data)
504- }
505-
506- if terminalRead == 0 {
507- return . closed
508- }
509-
510- if terminalRead < 0 {
511- if err == EAGAIN || err == EWOULDBLOCK || err == EINTR {
512- return . wouldBlock
513- }
514- if err == EIO {
515- return . closed
516- }
517- }
518-
519- return . closed
520- }
521-
522501 static func locateBundledHelper( _ name: String ) -> String ? {
523502 let fm = FileManager . default
524503
@@ -671,6 +650,7 @@ public struct TTYCommandRunner {
671650 var cleanedUp = false
672651 var launchedProcess : SpawnedProcessGroup ?
673652 var didExceedOutputLimit = false
653+ var didTerminateSynchronously = false
674654 /// Always tear down the PTY child (and its process group) even if we throw early
675655 /// while bootstrapping the CLI (e.g. when it prompts for login/telemetry).
676656 func cleanup( ) {
@@ -696,7 +676,9 @@ public struct TTYCommandRunner {
696676 try ? primaryHandle. close ( )
697677 launchedProcess. abortSynchronously ( )
698678 } else {
699- launchedProcess. terminateSynchronously ( )
679+ if !didTerminateSynchronously {
680+ launchedProcess. terminateSynchronously ( )
681+ }
700682 try ? primaryHandle. close ( )
701683 }
702684 TTYCommandRunnerActiveProcessRegistry . unregister ( pid: launchedProcess. pid)
@@ -952,7 +934,13 @@ public struct TTYCommandRunner {
952934
953935 let exitedBeforeDeadline = !stoppedEarly
954936 && process. exitObservationDate. map { $0 <= deadline } == true
955- let exitStatusBeforeDrain = exitedBeforeDeadline ? process. finishSynchronously ( ) : nil
937+ let exitStatusBeforeDrain : Int32 ?
938+ if exitedBeforeDeadline {
939+ exitStatusBeforeDrain = process. terminateSynchronously ( )
940+ didTerminateSynchronously = true
941+ } else {
942+ exitStatusBeforeDrain = nil
943+ }
956944
957945 func drainNonCodexOutput( for duration: TimeInterval ) throws -> Bool {
958946 let drainFor = max ( 0 , duration)
@@ -1189,6 +1177,27 @@ public struct TTYCommandRunner {
11891177}
11901178
11911179extension TTYCommandRunner {
1180+ static func drainReadResult( for data: Data , terminalRead: Int , errno err: Int32 ) -> DrainReadResult {
1181+ if !data. isEmpty {
1182+ return . data( data)
1183+ }
1184+
1185+ if terminalRead == 0 {
1186+ return . closed
1187+ }
1188+
1189+ if terminalRead < 0 {
1190+ if err == EAGAIN || err == EWOULDBLOCK || err == EINTR {
1191+ return . wouldBlock
1192+ }
1193+ if err == EIO {
1194+ return . closed
1195+ }
1196+ }
1197+
1198+ return . closed
1199+ }
1200+
11921201 static func withIsolatedActiveProcessRegistryForTesting< T> ( _ operation: ( ) throws -> T ) rethrows -> T {
11931202 try TTYCommandRunnerActiveProcessRegistry . withIsolatedStateForTesting ( operation)
11941203 }
0 commit comments