The Linux Programming Interface

(nextflipdebug5) #1

1256 Chapter 61


61.2 The shutdown() System Call


Calling close() on a socket closes both halves of the bidirectional communication
channel. Sometimes, it is useful to close one half of the connection, so that data can
be transmitted in just one direction through the socket. The shutdown() system call
provides this functionality.

The shutdown() system call closes one or both channels of the socket sockfd, depend-
ing on the value of how, which is specified as one of the following:
SHUT_RD
Close the reading half of the connection. Subsequent reads will return
end-of-file (0). Data can still be written to the socket. After a SHUT_RD on a
UNIX domain stream socket, the peer application receives a SIGPIPE signal and
the EPIPE error if it makes further attempts to write to the peer socket. As dis-
cussed in Section 61.6.6, SHUT_RD can’t be used meaningfully for TCP sockets.
SHUT_WR
Close the writing half of the connection. Once the peer application has
read all outstanding data, it will see end-of-file. Subsequent writes to the
local socket yield the SIGPIPE signal and an EPIPE error. Data written by the peer
can still be read from the socket. In other words, this operation allows us to
signal end-of-file to the peer while still being able to read data that the peer
sends back to us. The SHUT_WR operation is employed by programs such as
ssh and rsh (refer to Section 18.5 of [Stevens, 1994]). The SHUT_WR operation
is the most common use of shutdown(), and is sometimes referred to as a
socket half-close.
SHUT_RDWR
Close both the read and the write halves of the connection. This is the
same as performing a SHUT_RD followed by a SHUT_WR.
Aside from the semantics of the how argument, shutdown() differs from close() in
another important respect: it closes the socket channel(s) regardless of whether
there are other file descriptors referring to the socket. (In other words, shutdown()
is performing an operation on the open file description, rather than the file descriptor.
See Figure 5-1, on page 91.) Suppose, for example, that sockfd refers to a connected
stream socket. If we make the following calls, then the connection remains open,
and we can still perform I/O on the connection via the file descriptor fd2:

fd2 = dup(sockfd);
close(sockfd);

#include <sys/socket.h>

int shutdown(int sockfd, int how);
Returns 0 on success, or –1 on error
Free download pdf