fix(sessions): stop a duplicate inheriting a deleted directory - #171
Merged
Conversation
The persistent-session cwd probe descends screen's process tree and reads /proc/<pid>/cwd of the deepest process. The kernel resolves that link to "<path> (deleted)" once the directory is unlinked, and the probe took it verbatim: it reached the cwd store, the SFTP panel's follow-cwd, and the initial_cwd a duplicated session cds into. That cd can never succeed, and its error is discarded, so duplicating a session whose foreground program was pinned to a since-removed directory (a deleted worktree, say) landed silently in the home directory instead. Only count a candidate whose directory still exists, so the walk falls back to the last descendant with a live cwd -- the shell itself -- and refuse the "(deleted)" form again where the probe output is ingested, for hosts whose readlink behaves differently. The descent moves into a constant so the test can run it against a real three-level process tree with a directory removed underneath it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug
Duplicating a session opened it in the home directory instead of the source session's directory. Reported after it had been working, with the SFTP panel's follow-cwd still tracking correctly on the same host.
Root cause
Found in the process table of a live session. Its screen wrapper carried:
The
cdfired, at a path ending in the literal string(deleted). It failed,2>/dev/nullate the error, the shell stayed in$HOME.cwd_probe_commanddescends screen's process tree and reads/proc/<pid>/cwdof the deepest process. Linux resolves that link to<path> (deleted)once the directory is unlinked, and the probe accepted it raw. From there it flowed through thessh-cwd-<id>event into the cwd store, and out again as theinitial_cwda duplicate cds into.Nothing in the duplicate feature changed — the failure needed only a long-lived program (an editor, an agent) pinned to a directory that was later removed. Here that was a merged PR's worktree.
The fix
cwd_probe_command— only count a candidate whose directory still exists:[ -d "/path (deleted)" ]is false, so dead paths are rejected without a stripping heuristic, and the walk falls back to the last descendant with a live cwd: the shell. Dropping the descent's in-script comments also shrinks the base64 payload the dropbearMAX_EXEC_COMMAND_LENbudget has to fit.Ingestion —
is_live_probe_cwd()rejects non-absolute output and the(deleted)form where the poll loop reads the probe, for hosts whosereadlinkbehaves differently. Single producer, single consumer, so there is one guard rather than two copies.Tests
descent_ignores_a_descendant_whose_directory_was_removedruns the descent against a real three-level process tree (start → shell inlive→sleepindoomed), waits until the walk reaches the deepest process, removesdoomedunder it, and asserts the descent returnslive. Linux-gated, since the probe is/proc-only.Verified red without the fix:
probe_cwd_must_be_an_absolute_live_pathcovers the predicate directly.cargo test --lib shell_integration::— 21 passed, 0 failed.cargo fmt --checkclean. The 3commands::plugins::failures in a full--librun are unrelated:SEEDED_PLUGINSis empty without built plugin bundles, and they fail identically on cleandev.Out of scope
A shell genuinely sitting in a deleted directory still puts the duplicate in
$HOMEwith no explanation, since the remotecddiscards its error.