From a473e2f424c6894fdacb3574af4eac37d7b003c0 Mon Sep 17 00:00:00 2001 From: Rob von Behren Date: Thu, 7 May 2026 20:57:53 -0700 Subject: [PATCH 1/2] Fix test script to work without lsof on CI Use ss or fuser as fallbacks when lsof is not available, and warn gracefully if none are present. Co-Authored-By: Claude Opus 4.6 --- scripts/test | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/scripts/test b/scripts/test index a066eccc3..71a1e8e6b 100755 --- a/scripts/test +++ b/scripts/test @@ -14,9 +14,18 @@ function steady_is_running() { } kill_server_on_port() { - pids=$(lsof -t -i tcp:"$1" || echo "") + if command -v lsof >/dev/null 2>&1; then + pids=$(lsof -t -i tcp:"$1" || echo "") + elif command -v ss >/dev/null 2>&1; then + pids=$(ss -tlnp "sport = :$1" 2>/dev/null | grep -oP 'pid=\K[0-9]+' || echo "") + elif command -v fuser >/dev/null 2>&1; then + pids=$(fuser "$1/tcp" 2>/dev/null || echo "") + else + echo "Warning: no tool available to find processes on port $1" + return + fi if [ "$pids" != "" ]; then - kill "$pids" + kill $pids echo "Stopped $pids." fi } From de5cd259b37c91bef7ca582069865034ecdcdc27 Mon Sep 17 00:00:00 2001 From: Rob von Behren Date: Thu, 7 May 2026 21:20:14 -0700 Subject: [PATCH 2/2] Add /proc fallback for finding processes on a port When lsof, ss, and fuser are all unavailable, parse /proc/net/tcp to find socket inodes listening on the target port, then scan /proc/*/fd/ to map inodes back to pids. Always available on Linux. Co-Authored-By: Claude Opus 4.6 --- scripts/test | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/scripts/test b/scripts/test index 71a1e8e6b..ddfc3036b 100755 --- a/scripts/test +++ b/scripts/test @@ -13,6 +13,28 @@ function steady_is_running() { curl --silent "http://127.0.0.1:4010/_x-steady/health" >/dev/null 2>&1 } +find_pids_on_port_via_proc() { + # Parse /proc/net/tcp{,6} to find socket inodes listening on the port, + # then scan /proc/*/fd/ to find which pids own those sockets. + local port_hex + port_hex=$(printf '%04X' "$1") + local inodes + inodes=$(awk -v ph="$port_hex" '$2 ~ ":"ph"$" && $4 == "0A" {print $10}' /proc/net/tcp /proc/net/tcp6 2>/dev/null | sort -u) + [ -z "$inodes" ] && return + local pids="" + for inode in $inodes; do + for fd in /proc/[0-9]*/fd/*; do + if [ "$(readlink "$fd" 2>/dev/null)" = "socket:[$inode]" ]; then + local pid="${fd#/proc/}" + pid="${pid%%/fd/*}" + pids="$pids $pid" + break + fi + done + done + echo "$pids" | xargs +} + kill_server_on_port() { if command -v lsof >/dev/null 2>&1; then pids=$(lsof -t -i tcp:"$1" || echo "") @@ -20,6 +42,8 @@ kill_server_on_port() { pids=$(ss -tlnp "sport = :$1" 2>/dev/null | grep -oP 'pid=\K[0-9]+' || echo "") elif command -v fuser >/dev/null 2>&1; then pids=$(fuser "$1/tcp" 2>/dev/null || echo "") + elif [ -d /proc/net ]; then + pids=$(find_pids_on_port_via_proc "$1") else echo "Warning: no tool available to find processes on port $1" return