From 3361b4d983af139151deb939d8cb9a4fe28f61ef Mon Sep 17 00:00:00 2001 From: Camden Narzt <6243207+CamJN@users.noreply.github.com> Date: Sun, 1 Nov 2026 03:55:43 -0700 Subject: [PATCH] Make daemon_controller's socket ping confirm the connection On 2026-11-01 warp macOS CI runners, a non-blocking connect to a closed loopback TCP port completes without an error, even though the socket never becomes connected (after connecting getpeername fails with EINVAL). ping_socket took that as "something is listening", so closed ports looked open. This broke passenger macOS Nginx integration tests: NginxController#stop waits until the test port stops answering, which never happened, so each test group timed out after 30 seconds. Added diagnostics confirmed that no process was listening on that port and ports that nothing was using behaved the same way. The same ping is used to decide when Passenger Standalone considers its server started. ping_socket now asks for the peer address before reporting success, and treats ENOTCONN or EINVAL as "not listening". Signed-off-by: Camden Narzt <6243207+CamJN@users.noreply.github.com> --- lib/daemon_controller.rb | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/daemon_controller.rb b/lib/daemon_controller.rb index 4206ce9..16c0fdb 100644 --- a/lib/daemon_controller.rb +++ b/lib/daemon_controller.rb @@ -705,7 +705,7 @@ def ping_socket(socket_domain, sockaddr) raise Errno::ECONNREFUSED end end - true + socket_connected?(socket) rescue Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::ENOENT # ECONNRESET: the connection landed in the listen backlog of a # server that closed its listening socket before accepting it, @@ -715,6 +715,17 @@ def ping_socket(socket_domain, sockaddr) socket.close if socket end + # Some macOS systems (seen on warp CI runners in 2026) report a nonblocking + # connect to a closed TCP port as successful, so ping_socket confirms the + # connection by asking for the peer address. macOS fails that call with + # EINVAL instead of ENOTCONN when the connection attempt has failed. + def socket_connected?(socket) + socket.getpeername + true + rescue Errno::ENOTCONN, Errno::EINVAL + false + end + def ping_tcp_socket(sockaddr) ping_socket(Socket::Constants::AF_INET, sockaddr) rescue Errno::EAFNOSUPPORT