Dealing with
Duplicated Sockets
If a socket's
file descriptor is duplicated with the help of a dup(2) or a dup2(2) function
call, then only the last outstanding close(2) call actually closes down the
socket. This happens because the other
duplicated file descriptors are still considered to be in use. This is
demonstrated in the following code:
Example
int s; /* Existing socket
*/
int
d; /* Duplicated socket */
d = dup(s); /* duplicate this socket
*/
close(s); /* nothing happens yet */
close(d); /* last close, so shutdown
socket */
In the example,
the first close(2) call would have no effect. It would make no difference which
socket was closed first. Closing either s or d first would still leave one
outstanding file descriptor for the same socket. Only when closing the last
surviving file descriptor for that socket would a close(2) call have any
effect. In the example, the close of the d file descriptor closes down the
socket.
The shutdown(2)function avoids this difficulty. Repeating the example code, the problem is
solved using the shutdown(2) function:
Example
int
s; /* Existing socket */
int
d; /* Duplicated socket */
d = dup(s); /* duplicate this socket
*/
shutdown(s,SHUT_RDWR); /* immediate shutdown */
Even though the
socket s is also open on file unit d, the shutdown(2) function
immediately causes the socket to perform its shutdown duties as requested. This
naturally affects both the open file descriptors
s and d because they both refer to the same socket.
Another way this
problem is manifested is after a fork(2) function has been called upon. Any
sockets that existed prior to a fork operation would be duplicated in the child
process.
TIP
Use the
shutdown(2) function instead of the close(2) function whenever immediate or
partial shutdown action is required. Duplicated file descriptors from dup(2),
dup2(2), or fork(2) operations can prevent a close(2) function from initiating
any shutdown action until the last outstanding descriptor is closed.
No comments:
Post a Comment