bug: Shell server (vsock) does not allocate PTY interactive signal handling broken #70
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?
Description
The shell server in my_hypervisor-init listening on vsock port 1025 runs an interactive shell without allocating a pseudo-terminal (PTY). This breaks interactive terminal behavior when connecting via the web console or my_hypervisor attach.
Steps to Reproduce
Option A: Via Hero Compute web console
Option B: Via chvm CLI
my_hypervisor attach test-pty
Option C: Via raw vsock connection
echo "CONNECT 1025" | socat - UNIX-CONNECT:~/.chvm/vms//vsock.sock
Actual Result
ping 1.1.1.1
PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
64 bytes from 1.1.1.1: icmp_seq=1 ttl=56 time=5.49 ms
64 bytes from 1.1.1.1: icmp_seq=2 ttl=56 time=5.60 ms
^C^C64 bytes from 1.1.1.1: icmp_seq=3 ttl=56 time=5.53 ms
^C^C^C^C^C64 bytes from 1.1.1.1: icmp_seq=4 ttl=56 time=5.51 ms
^C^C^C64 bytes from 1.1.1.1: icmp_seq=5 ttl=56 time=5.57 ms
Expected Result
64 bytes from 1.1.1.1: icmp_seq=2 ttl=56 time=5.60 ms
^C
--- 1.1.1.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 5.490/5.545/5.600/0.055 ms
root@vm:~#
Root Cause
The shell server spawns a shell process (/bin/bash or /bin/sh) with raw stdin/stdout pipes but no PTY.
Without a PTY:
Suggested Fix
The shell server should allocate a PTY pair using openpty()/forkpty():
This enables the kernel's terminal line discipline which handles:
Affected Components
Environment
bug: Shell server (vsock port 1025) does not allocate PTY interactive signal handling brokento bug: Shell server (vsock) does not allocate PTY interactive signal handling brokenImplementation Spec for Issue #70: PTY Controlling Terminal for Shell Server
Objective
Fix the shell server (vsock port 1025) so the spawned shell has a proper controlling terminal, enabling interactive signal handling (Ctrl+C → SIGINT, Ctrl+Z → SIGTSTP, Ctrl+D → EOF).
Background Analysis
The shell handler at
crates/my_hypervisor-init/src/shell_handler.rsalready allocates a PTY pair viaopen_pty(). However, it has two critical defects:setsid()before spawning the shell. The shell process inherits the session of the init process. Without a new session, the PTY slave cannot become the controlling terminal.TIOCSCTTYioctl. The slave was opened withO_NOCTTY, preventing it from becoming the controlling terminal. An explicitTIOCSCTTYcall is needed.Requirements
setsid()) with the PTY slave as its controlling terminal (TIOCSCTTY)isatty()must gettrueFile Modified
crates/my_hypervisor-init/src/shell_handler.rssetsid()+TIOCSCTTYinpre_exec; removeO_NOCTTYfrom slave openImplementation
use std::os::unix::io::AsRawFdanduse std::os::unix::process::CommandExtimportsslave_raw_fdviaAsRawFdbefore cloning the slave for stdin/stdout/stderrunsafe pre_execclosure on the Command that:libc::setsid()to create a new session (makes bash the session leader)libc::ioctl(slave_raw_fd, libc::TIOCSCTTY, 0)to set the PTY slave as the controlling terminalO_NOCTTYfrom the slaveopen()call inopen_pty()Acceptance Criteria
chvm attach <vm>connects to a shell wherettyprints/dev/pts/Nping 1.1.1.1is interrupted by Ctrl+C)catis suspended)isatty()returns true (e.g.,lsshows colors,python3shows interactive prompt)chvm exec <vm> -- ls -la(non-interactive) continues to workcargo test --workspacepassescargo clippy -- -D warningspassesTest Results
Branch:
developmentCommit:
243e61fDate: 2026-03-26
Clippy
--workspace -- -D warnings(strict, warnings are errors)Unit Tests
Breakdown by crate:
my_hypervisor-climy_hypervisor-initmy_hypervisor-libImplementation Summary
Changes Made
1 file modified:
crates/my_hypervisor-init/src/shell_handler.rssetsid()call in child processpre_execto create a new session, detaching from init's sessionTIOCSCTTYioctl to make the PTY slave the controlling terminalO_NOCTTYflag from slave PTY open callWhat This Fixes
ping)isatty()returns true (enables colors, interactive prompts, line editing)ttycommand prints/dev/pts/Ninstead of "not a tty"Test Results