Enforce single-instance in socktop-gestures instead of documenting it

The documented restart was `pkill -x lisgd && socktop-gestures &`. pkill exits
non-zero when it matches nothing, so `&&` short-circuits and the daemon
silently does not start when none was running -- you swipe, get nothing, and
reasonably blame the config change you just made. socktop-gestures exec'd lisgd
with no guard, so nothing downstream caught it.

Rather than only fixing the one-liner, move the invariant into the tool: it now
exits non-zero if a daemon is already running, and --replace stops the old one
first (waiting for it to actually exit). This is the failure the README itself
flags as gotcha 3, so a false success there is expensive.

Verified against a live daemon: refusal, --help, bad-option exit codes, and a
clean pid handover under --replace with the carousel still working.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
jasonwitty
2026-08-09 02:29:36 -07:00
parent 18ddd39184
commit 9a47fd47a7
3 changed files with 60 additions and 15 deletions
+42 -1
View File
@@ -25,7 +25,48 @@ SWIPE_CMD=${SWIPE_CMD:-$(dirname "$0")/socktop-swipe}
[ -x /usr/local/bin/socktop-swipe ] && SWIPE_CMD=/usr/local/bin/socktop-swipe
verbose=
[ "${1:-}" = "-v" ] && verbose=-v
replace=no
for a in "$@"; do
case "$a" in
-v) verbose=-v ;;
--replace) replace=yes ;;
-h | --help)
echo "usage: socktop-gestures [-v] [--replace]"
echo " -v log each detected gesture"
echo " --replace stop an already-running daemon first"
exit 0
;;
*)
echo "socktop-gestures: unknown option '$a'" >&2
exit 2
;;
esac
done
# Single-instance guard. lisgd does not grab the input device exclusively, so a
# second copy makes every swipe fire twice -- the carousel appears to skip panes.
# Enforced here rather than left to the caller: the obvious restart one-liner
# `pkill -x lisgd && socktop-gestures` silently starts NOTHING when no daemon was
# running, because pkill exits non-zero when it matches nothing.
running=$(pgrep -x -u "$(id -u)" lisgd 2>/dev/null || true)
if [ -n "$running" ]; then
if [ "$replace" = yes ]; then
pkill -x -u "$(id -u)" lisgd || true
n=0
while pgrep -x -u "$(id -u)" lisgd >/dev/null 2>&1 && [ "$n" -lt 30 ]; do
n=$((n + 1))
sleep 0.1
done
if pgrep -x -u "$(id -u)" lisgd >/dev/null 2>&1; then
echo "socktop-gestures: existing lisgd would not exit" >&2
exit 1
fi
else
echo "socktop-gestures: lisgd is already running (pid: $(echo "$running" | tr '\n' ' '))" >&2
echo " Two instances make every swipe fire twice. Use --replace to restart it." >&2
exit 1
fi
fi
if [ ! -e "$TOUCH_DEV" ]; then
echo "socktop-gestures: $TOUCH_DEV not present" >&2