Commit 2e2c4c6
fix(cli): restore terminal state after Ctrl+C in interactive commands (#1407)
When interrupting `vp dev` or `vp preview` with Ctrl+C on Unix terminals
(particularly macOS/Ghostty), escape sequences appeared in the shell
prompt. This occurred because Vite sets the terminal to raw mode for
interactive features, and when SIGINT interrupted the child process, the
terminal state wasn't restored before the parent exited.
## Changes
- **`crates/vite_command/src/lib.rs`**:
- Added `TerminalStateGuard` RAII guard that saves terminal attributes
via `tcgetattr()` on creation and restores via `tcsetattr()` on drop
- Added `execute_with_terminal_guard()` wrapper function that applies
the guard during command execution
- Guard only activates when stdin is a TTY, safely ignoring
pipes/redirects
- **`packages/cli/binding/src/cli/execution.rs`**:
- Modified `resolve_and_execute()` to detect interactive commands
(`Dev`, `Preview`)
- Routes interactive commands through terminal guard wrapper
- Non-interactive commands use standard execution path unchanged
- **`crates/vite_command/Cargo.toml`**:
- Added `"term"` feature to `nix` dependency for terminal state APIs
## Implementation
```rust
// Terminal state saved before spawning child
let _guard = TerminalStateGuard::save(STDIN_FILENO);
// Child runs with inherited stdio
let mut child = cmd.spawn()?;
child.wait().await?
// Guard's Drop impl automatically restores terminal on exit,
// even if interrupted by signal
```
The fix follows the same RAII pattern used in
`vite_shared/src/header.rs` for raw mode management and only impacts
interactive dev servers where terminal corruption can occur.
---------
Co-authored-by: anthropic-code-agent[bot] <242468646+Claude@users.noreply.github.com>
Co-authored-by: Brooooooklyn <3468483+Brooooooklyn@users.noreply.github.com>
Co-authored-by: LongYinan <lynweklm@gmail.com>1 parent abc3b2a commit 2e2c4c6
File tree
3 files changed
+88
-4
lines changed- crates/vite_command
- src
- packages/cli/binding/src/cli
3 files changed
+88
-4
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
19 | | - | |
| 19 | + | |
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
1 | 3 | | |
2 | 4 | | |
3 | 5 | | |
| |||
59 | 61 | | |
60 | 62 | | |
61 | 63 | | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
62 | 90 | | |
63 | 91 | | |
64 | 92 | | |
| |||
230 | 258 | | |
231 | 259 | | |
232 | 260 | | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
233 | 305 | | |
234 | 306 | | |
235 | 307 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
57 | 57 | | |
58 | 58 | | |
59 | 59 | | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
60 | 65 | | |
61 | 66 | | |
62 | 67 | | |
63 | | - | |
64 | | - | |
65 | | - | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
66 | 78 | | |
67 | 79 | | |
68 | 80 | | |
| |||
0 commit comments