feat: party clean removes the caller's own crash leftovers
Turns the manual rm -rf recovery from host's EEXIST message into a verb, behind the same gates cmd_close uses: own-basename glob, no symlinks, ownership check, and a dead socket. Live parties are skipped with a pointer to party close.
This commit is contained in:
parent
6799a57405
commit
a011e4b03c
6 changed files with 133 additions and 9 deletions
47
party
47
party
|
|
@ -49,6 +49,7 @@ Hosting:
|
|||
Names: letters, digits, '_', '-' (max 63).
|
||||
close [name] Tear down the party you host (name it when
|
||||
you host several).
|
||||
clean Remove your own dead party dirs (crash leftovers).
|
||||
|
||||
Joining:
|
||||
join [name] [--passive] Join a party. Without name: auto-pick or numbered prompt.
|
||||
|
|
@ -764,14 +765,14 @@ EOF
|
|||
# races with a concurrent in-flight setup: two processes both seeing a
|
||||
# stale dir would both rm -rf it, and the loser's late rm -rf would
|
||||
# wipe the winner's freshly-created replacement.
|
||||
# The recovery path for genuine crash leftovers is a one-shot manual
|
||||
# `rm -rf $party_dir` followed by retry; the error message says so.
|
||||
# The recovery path for genuine crash leftovers is `party clean`
|
||||
# followed by retry; the error message says so.
|
||||
if ! mkdir -m 0700 "$party_dir" 2>/dev/null; then
|
||||
cat >&2 <<EOF
|
||||
party: $party_dir already exists. Either another host is starting '$name'
|
||||
right now, or a prior crashed attempt left this directory behind. If no
|
||||
other host is in flight, remove the directory and retry:
|
||||
rm -rf $party_dir
|
||||
other host is in flight, clean up and retry:
|
||||
party clean
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -946,6 +947,43 @@ cmd_close() {
|
|||
rm -rf "$expected_dir"
|
||||
echo "Party '$name' closed."
|
||||
}
|
||||
|
||||
cmd_clean() {
|
||||
case "${1:-}" in
|
||||
-h|--help)
|
||||
cat <<'EOF'
|
||||
Usage: party clean
|
||||
Remove your own dead party directories (crash leftovers whose tmux
|
||||
server is gone). Live parties and other users' directories are never
|
||||
touched; end a live party with `party close`.
|
||||
EOF
|
||||
exit 0 ;;
|
||||
'') ;;
|
||||
*) echo "party clean: unexpected arg '$1'" >&2; exit 2 ;;
|
||||
esac
|
||||
|
||||
# Same mistake-proofing gates as cmd_close: the glob only matches
|
||||
# the caller's own basename prefix, symlinks are never followed,
|
||||
# [ -O ] pins ownership, and a socket answering the tmux protocol
|
||||
# means the party is live and gets skipped, `party close` is the
|
||||
# verb for those. An unmatched glob stays a literal string and
|
||||
# fails [ -d ].
|
||||
removed=0
|
||||
for d in "$PARTY_SOCKET_DIR"/party-"$USER":*.d; do
|
||||
[ -d "$d" ] || continue
|
||||
[ -L "$d" ] && continue
|
||||
[ -O "$d" ] || continue
|
||||
if [ -e "$d/sock" ] \
|
||||
&& [ "$(party_conn_state "$d/sock")" != dead ]; then
|
||||
echo "party clean: skipping $d (server is live; use party close)." >&2
|
||||
continue
|
||||
fi
|
||||
rm -rf "$d"
|
||||
echo "removed $d"
|
||||
removed=$((removed+1))
|
||||
done
|
||||
[ "$removed" -gt 0 ] || echo "nothing to clean."
|
||||
}
|
||||
cmd_join() {
|
||||
passive=0
|
||||
name=
|
||||
|
|
@ -1547,6 +1585,7 @@ dispatch() {
|
|||
--version) echo "party $PARTY_VERSION"; exit 0 ;;
|
||||
host) cmd_host "$@" ;;
|
||||
close) cmd_close "$@" ;;
|
||||
clean) cmd_clean "$@" ;;
|
||||
join) cmd_join "$@" ;;
|
||||
leave) cmd_leave "$@" ;;
|
||||
knock) cmd_knock "$@" ;;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue