Skip to content

Commit 6af87ab

Browse files
branchseerclaude
andcommitted
fix(vite_pty): drop slave after spawn to signal EOF on child exit
Drop the PTY slave handle immediately after spawning the child process. This ensures EOF is signaled on the reader when the child exits, which is critical for the zig linker builds where the slave handle was keeping the PTY open. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent c585eb6 commit 6af87ab

File tree

1 file changed

+9
-6
lines changed

1 file changed

+9
-6
lines changed

crates/vite_pty/src/terminal.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ use std::{
55
};
66

77
pub use portable_pty::CommandBuilder;
8-
use portable_pty::{ChildKiller, ExitStatus, PtyPair};
8+
use portable_pty::{ChildKiller, ExitStatus, MasterPty};
99

1010
use crate::geo::ScreenSize;
1111

1212
/// A headless terminal
1313
pub struct Terminal {
14-
pty_pair: PtyPair,
14+
master: Box<dyn MasterPty + Send>,
1515
parser: vt100::Parser<Vt100Callbacks>,
1616
child_killer: Box<dyn ChildKiller + Send + Sync>,
1717
reader: Box<dyn Read + Send>,
@@ -72,10 +72,13 @@ impl Terminal {
7272
})?;
7373
// Create reader BEFORE spawning child to ensure it's ready for data
7474
let reader = pty_pair.master.try_clone_reader()?;
75-
let mut child = pty_pair.slave.spawn_command(cmd)?;
76-
let child_killer = child.clone_killer();
7775
let writer: Arc<Mutex<Option<Box<dyn Write + Send>>>> =
7876
Arc::new(Mutex::new(Some(pty_pair.master.take_writer()?)));
77+
// Spawn child and immediately drop slave to ensure EOF is signaled when child exits
78+
let mut child = pty_pair.slave.spawn_command(cmd)?;
79+
let child_killer = child.clone_killer();
80+
drop(pty_pair.slave); // Critical: drop slave so EOF is signaled when child exits
81+
let master = pty_pair.master;
7982
let exit_status: Arc<OnceLock<ExitStatus>> = Arc::new(OnceLock::new());
8083

8184
// Background thread: wait for child to exit, set exit status, then close writer to trigger EOF
@@ -93,7 +96,7 @@ impl Terminal {
9396
});
9497

9598
Ok(Self {
96-
pty_pair,
99+
master,
97100
parser: vt100::Parser::new_with_callbacks(
98101
size.rows,
99102
size.cols,
@@ -266,7 +269,7 @@ impl Terminal {
266269
/// Returns an error if the PTY cannot be resized.
267270
pub fn resize(&mut self, size: ScreenSize) -> anyhow::Result<()> {
268271
// Resize the underlying PTY via portable-pty's MasterPty::resize
269-
self.pty_pair.master.resize(portable_pty::PtySize {
272+
self.master.resize(portable_pty::PtySize {
270273
rows: size.rows,
271274
cols: size.cols,
272275
pixel_width: 0,

0 commit comments

Comments
 (0)