From d68fcd9fc4efd853bca40dac7d4fcd6126961515 Mon Sep 17 00:00:00 2001 From: Joel Teply Date: Tue, 28 Apr 2026 09:16:57 -0500 Subject: [PATCH] refactor(airc): _reexec_into helper consolidates 5 duplicated exec sites (#205 target 1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Net: -15 lines (38 deletions, 23 additions). First compression PR per #205's net-negative-diff mandate from Joel. Five sites in cmd_connect previously duplicated the same 3-line pattern: local _preserved_name; _preserved_name=\$(get_config_val name "") _write_reexec_marker exec env [\${AIRC_NO_DISCOVERY=1}] \${_preserved_name:+AIRC_NAME=\$_preserved_name} "\$0" connect That's 5 × 3 = 15 lines of copy-paste, three of which were stale-host- takeover paths that diverged from the rejoin-race-loser paths only by the AIRC_NO_DISCOVERY=1 prefix. Plus 3 inline comment paragraphs explaining what the exec was for, also duplicated. Now: one helper _reexec_into , mode in {rejoin, host}. Folds in the sentinel marker write (used to be its own _write_reexec_ marker function with 11-line block comment — collapsed into helper). Five call sites become one line each. Behavior unchanged: same env vars passed in same way, same exec arguments, same marker file written. Only the structure changed. Bonus: caller can no longer forget to call _write_reexec_marker before exec — the only path is via _reexec_into which always writes it. (Pre-fix, every new exec site was a fresh chance to forget it, which is exactly what triggered #203.) #205 Target 1 of 6. Joel's bar: every PR net-negative or extension- point-bearing. This is net-negative. --- airc | 71 +++++++++++++++++++++--------------------------------------- 1 file changed, 25 insertions(+), 46 deletions(-) diff --git a/airc b/airc index 189dad2..c55b3a6 100755 --- a/airc +++ b/airc @@ -292,20 +292,22 @@ unset _gh_resolved AIRC_WRITE_DIR="$(detect_scope)" -# Write a sentinel marker before any intentional `exec env ... "$0" ...` -# call, so the Windows daemon launcher .bat can distinguish "intentional -# re-exec into different mode" from "actual crash" (#203). On Linux/Mac -# `exec` is a true execve — the parent bash's PID becomes the new -# program, so the launcher script never observes an exit and the marker -# is harmless. On Windows MSYS-bash, exec is emulated as spawn-and-exit: -# the original bash exits + a new airc bash takes over. The launcher -# .bat sees the original bash exit, would normally treat it as a crash, -# and respawn — racing the new airc that just took over (Joel/continuum- -# b69f's #203 crashloop). Marker contents: "PID:UNIX_TIMESTAMP". Caller -# is responsible for invoking this immediately before exec. -_write_reexec_marker() { - local marker="$AIRC_WRITE_DIR/airc.reexec-marker" - printf '%d:%d\n' "$$" "$(date +%s)" > "$marker" 2>/dev/null || true +# Re-exec airc connect into a different mode (rejoin into another tab's +# gist or take over as host). Centralizes (a) the sentinel marker for +# the Windows daemon launcher (#203/#204 — distinguishes intentional +# re-exec from "actual crash"), (b) AIRC_NAME preservation across the +# exec, and (c) AIRC_NO_DISCOVERY=1 for host-takeover so the new +# instance won't re-find the just-deleted gist via gh's list-cache. +# Replaces 5 duplicated 3-line call sites in cmd_connect (#205 target 1). +_reexec_into() { + local mode="$1"; shift # "rejoin" or "host" + printf '%d:%d\n' "$$" "$(date +%s)" > "$AIRC_WRITE_DIR/airc.reexec-marker" 2>/dev/null || true + local _name; _name=$(get_config_val name "") + if [ "$mode" = "host" ]; then + exec env AIRC_NO_DISCOVERY=1 ${_name:+AIRC_NAME="$_name"} "$0" connect "$@" + else + exec env ${_name:+AIRC_NAME="$_name"} "$0" connect "$@" + fi } CONFIG="$AIRC_WRITE_DIR/config.json" IDENTITY_DIR="$AIRC_WRITE_DIR/identity" @@ -2191,21 +2193,17 @@ cmd_connect() { | awk -F'\t' -v re="airc room: ${resolved_room_name}\$" -v skip="$_resolved_gist_id" \ '$2 ~ re && $1 != skip { print $1; exit }') - local _preserved_name; _preserved_name=$(get_config_val name "") - rm -f "$CONFIG" - rm -f "$AIRC_WRITE_DIR/room_name" + rm -f "$CONFIG" "$AIRC_WRITE_DIR/room_name" if [ -n "$_new_picked" ]; then echo " ✓ Another tab beat us to it — joining their fresh gist ($_new_picked)" echo "" - _write_reexec_marker - exec env ${_preserved_name:+AIRC_NAME="$_preserved_name"} "$0" connect "$_new_picked" + _reexec_into rejoin "$_new_picked" fi echo " Re-execing into host mode for #${resolved_room_name}..." echo "" - _write_reexec_marker - exec env AIRC_NO_DISCOVERY=1 ${_preserved_name:+AIRC_NAME="$_preserved_name"} "$0" connect --room "$resolved_room_name" + _reexec_into host --room "$resolved_room_name" fi # Parse name@user@host[:port]#pubkey @@ -2391,30 +2389,19 @@ except Exception: | awk -F'\t' -v re="airc room: ${resolved_room_name}\$" -v skip="$_resolved_gist_id" \ '$2 ~ re && $1 != skip { print $1; exit }') - # Preserve identity name across re-exec (same reason as resume - # path: derive_name re-runs from cwd and can drift on case- - # aliasing, peers see a "new" peer). - local _preserved_name; _preserved_name=$(get_config_val name "") # Wipe the CONFIG we just wrote — it points at the dead host # and would trigger 'resume joiner' on next airc connect. - rm -f "$CONFIG" - rm -f "$AIRC_WRITE_DIR/room_name" + rm -f "$CONFIG" "$AIRC_WRITE_DIR/room_name" if [ -n "$_new_picked" ]; then echo " ✓ Another tab beat us to it — joining their fresh gist ($_new_picked)" echo "" - # Re-exec as joiner pointing at the winner's gist. - _write_reexec_marker - exec env ${_preserved_name:+AIRC_NAME="$_preserved_name"} "$0" connect "$_new_picked" + _reexec_into rejoin "$_new_picked" fi echo " Re-execing into host mode for #${resolved_room_name}..." echo "" - # exec replaces the current bash process. AIRC_NO_DISCOVERY=1 - # prevents the new instance from re-finding the just-deleted gist - # (gh's gist-list cache might still show it for a few seconds). - _write_reexec_marker - exec env AIRC_NO_DISCOVERY=1 ${_preserved_name:+AIRC_NAME="$_preserved_name"} "$0" connect --room "$resolved_room_name" + _reexec_into host --room "$resolved_room_name" fi # Either not a room flow, or no gh, or no resolved_room_name → original die. # Surface the captured pair-handshake stderr (continuum-b69f 2026-04-27: @@ -2853,9 +2840,7 @@ JSON "$AIRC_WRITE_DIR/host_gist_id" \ "$AIRC_WRITE_DIR/room_gist_id" \ "$AIRC_WRITE_DIR/room_name" - local _preserved_name; _preserved_name=$(get_config_val name "") - _write_reexec_marker - exec env ${_preserved_name:+AIRC_NAME="$_preserved_name"} "$0" connect "$_winner_id" + _reexec_into rejoin "$_winner_id" fi fi @@ -5067,14 +5052,8 @@ _daemon_install_schtasks() { cwd_win=$(printf '%s' "$(pwd -P)" | sed 's|^/\([a-z]\)/|\U\1:\\\\|; s|/|\\\\|g') airc_bin_unix="$airc_bin" fi - # Marker path the daemon-launcher polls between iterations to - # distinguish "intentional re-exec into different mode" from "actual - # crash" (#203). airc itself writes this file via _write_reexec_marker - # right before any `exec env ... "$0" connect ...` call. On Windows - # MSYS-bash, exec is emulated as spawn-and-exit (not a true execve), - # so the launcher .bat sees the original bash exit while the new - # airc takes over — the marker tells the .bat to step aside instead - # of racing-respawn the new airc with another instance. + # Marker path the .bat polls to distinguish intentional re-exec + # (written by _reexec_into) from "actual crash" (#203/#204). local marker_win if command -v cygpath >/dev/null 2>&1; then marker_win=$(cygpath -w "$scope/airc.reexec-marker")