Closing a Socket After Forking
Problem
Your program has forked and you want to tell the other end that
you’re done sending data. You’ve tried
close
on the socket, but the remote end never gets
an EOF or SIGPIPE.
Solution
Use shutdown
:
shutdown(SOCKET, 0); # I/we have stopped reading data shutdown(SOCKET, 1); # I/we have stopped writing data shutdown(SOCKET, 2); # I/we have stopped using this socket
On an IO::Socket object, you could also write:
$socket->shutdown(0); # I/we have stopped reading data
Discussion
When a process forks, the child has copies of all the parent’s
open filehandles, including sockets. When you
close
a file or socket, you close only the current
process’ copy. If another process (parent or child) still has
the socket open, the operating system doesn’t consider their
file or socket closed.
Take the case of a socket that data is being sent to. If two processes have this socket open, one can close it but the socket isn’t considered closed by the operating system because the other still has it open. Until the other process closes the socket, the process reading from the socket won’t get an end-of-file. This can lead to confusion and deadlock.
To avoid this, either close
unused filehandles
after a fork
, or use shutdown
.
The shutdown
function is a more insistent form of
close
—it tells the operating system that even though other processes have copies of this filehandle, it should be marked as closed and the other end should get an end-of-file if they read from it, or a SIGPIPE ...
Get Perl Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.