Forward terminal window size (resize) to guest PTY via vsock #72
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Parent Issue
Split from #70 (PTY allocation for shell server). The PTY + controlling terminal fix is handled in #70. This issue covers the resize forwarding feature.
Problem
Terminal programs like
vim,htop,less, and multi-columnlsoutput need to know the terminal dimensions (rows x cols). Without resize forwarding:Proposed Solution
In-band resize protocol
Define an 8-byte escape sequence sent over the existing vsock byte stream:
0x01(SOH) is chosen because it essentially never appears in normal terminal output.Changes needed
crates/my_hypervisor-lib/src/vsock/protocol.rs— DefineRESIZE_MAGIC,RESIZE_MSG_LEN, andencode_resize()helpercrates/my_hypervisor-lib/src/vsock/proxy.rs— Ininteractive_session:TIOCGWINSZ) to guest before proxy loopSIGWINCHsignal to forward resize events in real-timecrates/my_hypervisor-init/src/shell_handler.rs— In vsock→PTY forwarding thread:TIOCSWINSZon PTY masterAcceptance Criteria
stty sizeinside the guest reflects the host terminal dimensionsstty sizebefore and after)vim,htop) render correctly0x01bytes is not corruptedcargo test --workspacepassescargo clippy -- -D warningspassesImplementation Spec for Issue #72
Objective
Implement terminal resize forwarding from the host to the guest VM via the existing vsock byte stream. When the host terminal window is resized, the new dimensions (rows, cols) are sent as an in-band escape sequence to the guest, which applies them to the PTY master fd using
TIOCSWINSZ.Requirements
[0x01, 0x52, 0x53, 0x5a] [rows: u16 BE] [cols: u16 BE]interactive_sessionstart, send the current host terminal dimensions to the guest before entering the proxy loopSIGWINCHon the host and forward updated dimensions in real-timeshell_handler, parse the vsock-to-PTY stream for the resize magic, extract rows/cols, apply viaTIOCSWINSZ, and do NOT forward the control bytes to the PTY0x01bytes must not be corruptedcargo test --workspace)cargo clippy -- -D warningspassesFiles to Modify
crates/my_hypervisor-lib/src/vsock/protocol.rsencode_resize()helpercrates/my_hypervisor-lib/src/vsock/proxy.rscrates/my_hypervisor-init/src/shell_handler.rsImplementation Plan
Step 1: Define the resize protocol in
protocol.rsRESIZE_MAGIC: [u8; 4]constant ([0x01, 0x52, 0x53, 0x5a])RESIZE_MSG_LEN: usize = 8encode_resize(rows: u16, cols: u16) -> [u8; 8]functionStep 2: Send initial winsize & handle SIGWINCH in
proxy.rsget_winsize() -> Option<(u16, u16)>helper usingTIOCGWINSZSIGWINCHhandler viatokio::signal::unix::signal(SignalKind::window_change())Step 3: Parse resize escape in guest
shell_handler.rsapply_winsize(master_fd, rows, cols)helper usingTIOCSWINSZStep 4: Add unit tests
test_encode_resize_known_valuesandtest_encode_resize_roundtripin protocol.rsStep 5: Build, lint, and verify
cargo build --workspacecargo test --workspacecargo clippy -- -D warningsAcceptance Criteria
stty sizeinside the guest reflects the host terminal dimensions at session start0x01bytes is not corruptedcargo test --workspacepasses (including new unit tests)cargo clippy -- -D warningspassesNotes
tokiosignal support andlibcalready available)0x01RSZmagic is safe — 4-byte sequence virtually never appears in terminal dataTIOCSWINSZon PTY master automatically sendsSIGWINCHto guest foreground process groupTest Results
-D warnings)All new resize protocol tests pass:
test_encode_resize_known_values✅test_encode_resize_roundtrip✅test_parser_passes_through_normal_data✅test_parser_detects_resize_message✅test_parser_handles_partial_magic_mismatch✅test_parser_handles_split_across_reads✅test_parser_0x01_in_normal_data✅test_parser_back_to_back_resize✅test_parser_data_around_resize✅Implementation Summary
Files Modified
crates/my_hypervisor-lib/src/vsock/protocol.rsRESIZE_MAGIC,RESIZE_MSG_LEN,encode_resize()+ 2 unit testscrates/my_hypervisor-lib/src/vsock/proxy.rsget_winsize(), initial winsize send, SIGWINCH handling ininteractive_session()crates/my_hypervisor-init/src/shell_handler.rsResizeParserstate machine,apply_winsize(), replaced direct vsock-to-PTY copy with parser + 7 unit testsHow it works
[\x01RSZ][rows:u16 BE][cols:u16 BE]proxy.rs): Sends initial terminal size before proxy loop; handlesSIGWINCHviatokio::signalto forward resize events in real-timeshell_handler.rs): State-machine parser in vsock-to-PTY thread detects resize messages, appliesTIOCSWINSZon PTY master (which auto-sendsSIGWINCHto foreground process), and strips control bytes from the data streamNotes
0x01bytes in normal data