Wednesday, September 21, 2011

duplicate socket handle


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