From 3f84a2ae4ab63343890ff90efca6d18b7292dd0f Mon Sep 17 00:00:00 2001 From: Matt Campbell Date: Fri, 4 Sep 2026 07:19:10 -0400 Subject: [PATCH] fix(ssh-agent): create screen/tmux symlink atomically (#14035) Co-authored-by: Carlo Sala --- plugins/ssh-agent/ssh-agent.plugin.zsh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/plugins/ssh-agent/ssh-agent.plugin.zsh b/plugins/ssh-agent/ssh-agent.plugin.zsh index 83548648b..4517242ec 100644 --- a/plugins/ssh-agent/ssh-agent.plugin.zsh +++ b/plugins/ssh-agent/ssh-agent.plugin.zsh @@ -101,10 +101,18 @@ if zstyle -t :omz:plugins:ssh-agent agent-forwarding \ && [[ -n "$SSH_AUTH_SOCK" ]]; then if [[ ! -L "$SSH_AUTH_SOCK" ]]; then if [[ -n "$TERMUX_VERSION" ]]; then - ln -sf "$SSH_AUTH_SOCK" "$PREFIX"/tmp/ssh-agent-$USERNAME-screen + _omz_ssh_agent_link="$PREFIX"/tmp/ssh-agent-$USERNAME-screen else - ln -sf "$SSH_AUTH_SOCK" /tmp/ssh-agent-$USERNAME-screen + _omz_ssh_agent_link=/tmp/ssh-agent-$USERNAME-screen fi + # `ln -sf` unlinks the old symlink and then creates the new one: two + # syscalls, no atomic swap. Shells starting concurrently (a tmux window + # opening several panes at once) interleave those steps and all but one + # fail with "ln: ...: File exists". Stage the link under a PID-unique + # name and move it into place, since rename(2) is atomic. + command ln -sf "$SSH_AUTH_SOCK" "$_omz_ssh_agent_link.$$" \ + && command mv -f "$_omz_ssh_agent_link.$$" "$_omz_ssh_agent_link" + unset _omz_ssh_agent_link fi else _start_agent