Use shutdown() ahead of close() for rlogin/ssh
Using only close() on a socket has a few issues: (1) poll is not required to wake on such events leading to hangs if infinite timeouts are used. This can be observed in macOS: (a) syncterm -iC (b) connect via telnet to some system (c) use the menu to disconnect from the system Note: socket must be idle to reproduce. (2) If a blocked recv/send receives an error in response to a close from another thread, the context of the socket has been lost: the descriptor is free to be reallocated under the thread performing I/O by the system. Any retry logic that may be written in response to the error condition could lead to operations being performed on a valid but incorrect resource. (3) Processes that inherited the socket via fork() will still have a valid descriptor to the socket. i.e., the socket does not globally shutdown via a call to close(); however, shutdown() acts on the connection by triggering a TCP FIN. This will lead to the actual shutdown of the socket by the remote connection as well. Solution: Use shutdown() ahead of close(). This will initiate a proper shutdown sequence on the socket while leaving the descriptor open. poll() will wake, and a subsequent read or write will yield the desired EOF/EPIPE.