Two issues:
- signal() on Linux sets SA_RESTART by default, causing sleep(1) to be
restarted after the signal handler runs. Switch to sigaction() with no
SA_RESTART flag and replace sleep(1) with pause() so the main thread
wakes and exits immediately on SIGINT/SIGTERM.
- close(sock_fd) is not guaranteed to unblock another thread blocked in
accept() on that fd. Add shutdown(SHUT_RDWR) before close() in
socket_server_stop() for both the listening socket and the client
socket, which reliably wakes blocked accept() and read() calls.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>