| Commit message (Collapse) | Author | Age |
| |
|
|
|
|
|
|
|
|
|
|
|
| |
* chore(deps): upgrade base64 0.22, colored 3.1, crossterm 0.29, dialoguer 0.11, directories 6.0, highway 1.2, prost 0.12.6, strip-ansi-escapes 0.2.1, suggest 0.5.1
* chore(deps): upgrade miette 7.6, nix 0.30, notify 8.2, notify-debouncer-full 0.5
* vte 0.15
* clap 4.6
* workspaceify plugin deps
* don't send empty fs watch events
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
table (#5324)
* build(deps): bump sysinfo to 0.37 for scan-free partial process refresh
Bump it to pull in sysinfo 0.37's change "Linux: greatly improve partial
processes retrieval", so that refreshing a specific set of pids
(ProcessesToUpdate::Some) no longer walks the entire /proc tree.
This makes the existing get_cwd/get_cwds polling O(panes) instead of
O(host processes) and unblocks doing the same for foreground-command discovery.
* perf: discover foreground pane commands w/o scanning all processes
Foreground command discovery was reading information about every process
on the host, on each pane/tab creation and on every periodic poll. On hosts
with many processes (eg, 50k) this stalled pane creation for tens of seconds
and overran the action-completion timeout.
Replace that O(host processes) lookup with an O(panes) lookup. Instead
of looking up the parent pid of every process to find the child, get
the foreground process-group leader's pid from a call to tcgetpgrp on
the pane's controlling terminal. When the leader is the shell itself
(idle prompt or a command sharing the shell's group without job control)
the pane is omitted and the caller falls back to the shell command,
matching prior behavior; with job control on it now reports the true
foreground job instead of possibly a background one.
This changes the paths for Linux, macOS, and BSD. It leaves Windows unchanged.
* refactor(os_input): extract apply_post_command_hook helper
The command -> run_command_hook -> trim/split pipeline was duplicated between
the #[cfg(not(unix))] get_all_cmds_by_ppid and the unix get_foreground_cmds.
Extract a single apply_post_command_hook helper and call it from both sites,
routing the hook-failure fallback through the project's non_fatal() logging
idiom (CONTRIBUTING.md "Logging errors") instead of log::error!.
* review: simplify tcgetpgrp locking, trim comments, drop changelog entries
- Remove the lock-drop dance and its TOCTOU caveat from tcgetpgrp,
to make it mirror tcdrain
- Prune AI comments
- Remove CHANGELOG entries
|
| | |
|
| |
|
|
|
|
|
| |
* don't reuse terminal pane_ids, perform some cleanups
* rustfmt
* add pr
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
(#4818)
* fix: handle short writes in write_to_tty_stdin to prevent paste truncation
On macOS the kernel PTY buffer is only 4-16 KiB, so a single write()
call for a large paste returns a short write count rather than blocking
until all bytes are accepted. The current code returns this partial
count without retrying, silently dropping the remaining bytes.
This wraps the write in a retry loop that handles:
- Short writes (advances the buffer offset and retries)
- EINTR (retries immediately)
- EAGAIN (sleeps 1ms then retries)
Without this fix, pasting ~1 KiB+ of text into a terminal pane loses
everything beyond the first kernel-buffer-full.
Includes a test that exercises the fix using a real PTY pair with
O_NONBLOCK set on the master fd to force short writes.
* fix: cap EAGAIN retries at 50 to prevent infinite busy-wait
Per reviewer feedback, add a retry counter that caps consecutive EAGAIN
retries at 50 and logs an error if the limit is reached. The counter
resets on any successful write progress, so it only triggers when the
PTY is genuinely stuck.
* fix: use poll(POLLOUT) instead of sleep-retry loop for EAGAIN handling
Replace the 50-retry sleep(1ms) busy-wait with poll(POLLOUT, 5s timeout).
This properly waits for fd writability without CPU spinning and returns
an error on timeout instead of silently returning Ok(partial) — which
the caller (pty_writer_main) would ignore, causing silent data loss.
Tests:
- write_to_tty_stdin_delivers_all_bytes: remove flaky reader delay,
use concurrent reader, move master close after reader join to avoid
macOS kernel buffer flush race
- write_all_to_fd_errors_on_stuck_pty: new test verifying timeout
returns Err on stuck PTY (uses 100ms timeout for speed)
* fix: re-queue partial PTY writes instead of blocking PtyWriter thread
Replace the poll(POLLOUT) blocking loop with a non-blocking re-queue
approach as suggested in review. On partial write or EAGAIN:
- write_to_tty_stdin now drains as much as the kernel accepts in one
pass and returns the count (may be 0 on EAGAIN)
- PtyWriter re-queues unwritten bytes back onto its own channel,
letting other terminals' writes proceed between retries
- Retry count tracks consecutive zero-progress attempts (reset on
any forward progress), drops bytes after 50 retries with log::error
- yield_now() before re-queue on zero progress to avoid tight spin
- Guard against write() returning Ok(0) on non-empty buffer
- Wire up PtyWriter's self-sender (was None, now Some(&to_pty_writer))
* fix: per-terminal write buffering to handle short writes and EAGAIN
Replace re-queue approach with per-terminal pending write buffers
(HashMap<u32, VecDeque<PendingWrite>>). Uses recv_timeout(10ms) when
pending data exists, blocking recv when idle. 10MB per-terminal cap
drops buffer on overflow. Terminal errors clear the queue.
Adds Bus::recv_timeout via crossbeam Select::select_timeout.
Removes tcdrain from write path.
* use safe accessor methods and saturating substitutions
* add tests for ptywriter
* rustfmt
* fix tests by not assuming kernel buffer sizes
* rustfmt
* add pr
---------
Co-authored-by: Aram Drevekenin <aram@poor.dev>
|
|
|
platform-split PTY backend (#4722)
* refactor: replace RawFd with i32 in debug_to_file
Replace the Unix-specific RawFd type with plain i32 in the debug_to_file
infrastructure. This removes the last RawFd usage from the cross-crate
debug logging API, making it platform-independent.
* refactor: cross-platform PTY abstraction with AsyncFd
Replace portable-pty with native openpty and introduce a platform-split
architecture for PTY operations:
- os_input_output_unix.rs: UnixPtyBackend with native openpty, AsyncFd-based
epoll reader (no spawn_blocking per pane), signal handling via nix
- os_input_output_windows.rs: WindowsPtyBackend stubs (unimplemented)
- os_input_output.rs: shared ServerOsApi trait, ServerOsInputOutput composes
PtyBackendImpl, build_command() extracts TerminalAction→RunCommand logic
Key changes:
- AsyncFd<File> replaces both tokio::fs::File (upstream) and spawn_blocking
SyncReadAsyncReader (previous port) for zero-overhead epoll PTY reads
- orig_termios restored: openpty(None, &orig_termios) passes parent's VERASE
- ServerOsApi returns Box<dyn AsyncReader> instead of Box<dyn Read + Send>
- TerminalBytes::new takes Box<dyn AsyncReader> directly
- NullAsyncReader replaces std::io::empty() for held panes
- Platform modules gated with #[cfg(not(windows))] / #[cfg(windows)]
- Removed portable-pty dependency, restored close_fds
- Added tokio "net" feature for AsyncFd
---------
Co-authored-by: divens <divens.dev@gmail.com>
|