shutdown用来关闭一个全双工连接的部分或者全部,比如关闭读,关闭写,或者读写全部关闭;

 /*
* Shutdown a socket.
*/ SYSCALL_DEFINE2(shutdown, int, fd, int, how)
{
int err, fput_needed;
struct socket *sock; /* 找到socket */
sock = sockfd_lookup_light(fd, &err, &fput_needed);
if (sock != NULL) {
err = security_socket_shutdown(sock, how);
if (!err)
/* 调用对应类型的shutdown */
err = sock->ops->shutdown(sock, how);
fput_light(sock->file, fput_needed);
}
return err;
}

inet_shutdown会根据连接的状态进行不同的处理,比如已连接状态需要调用传输层实现的shutdown,而监听或者发送了syn包会根据情况则调用传输层的disconnect等;

 /* 关闭操作 */
int inet_shutdown(struct socket *sock, int how)
{
struct sock *sk = sock->sk;
int err = ; /* This should really check to make sure
* the socket is a TCP socket. (WHY AC...)
*/
how++; /* maps 0->1 has the advantage of making bit 1 rcvs and
1->2 bit 2 snds.
2->3 */
/* how值错误 */
if ((how & ~SHUTDOWN_MASK) || !how) /* MAXINT->0 */
return -EINVAL; lock_sock(sk); /* 正在连接 */
if (sock->state == SS_CONNECTING) {
/* syn发送,syn接收,关闭状态 */
if (( << sk->sk_state) &
(TCPF_SYN_SENT | TCPF_SYN_RECV | TCPF_CLOSE))
/* 设置正在关闭连接 */
sock->state = SS_DISCONNECTING;
/* 否则为已连接状态 */
else
sock->state = SS_CONNECTED;
} switch (sk->sk_state) {
case TCP_CLOSE:
err = -ENOTCONN;
/* Hack to wake up other listeners, who can poll for
POLLHUP, even on eg. unconnected UDP sockets -- RR */
default:
/* 设置how值,并且调用传输层的shutdown */
sk->sk_shutdown |= how;
if (sk->sk_prot->shutdown)
sk->sk_prot->shutdown(sk, how);
break; /* Remaining two branches are temporary solution for missing
* close() in multithreaded environment. It is _not_ a good idea,
* but we have no choice until close() is repaired at VFS level.
*/
case TCP_LISTEN:
/* 监听状态,如果无接收方向的关闭操作,跳出 */
if (!(how & RCV_SHUTDOWN))
break;
/* 有接收方向的关闭,继续 */
/* Fall through */
case TCP_SYN_SENT:
/* 调用传输层的disconnect断开连接 */
err = sk->sk_prot->disconnect(sk, O_NONBLOCK); /* 调增状态 */
sock->state = err ? SS_DISCONNECTING : SS_UNCONNECTED;
break;
} /* Wake up anyone sleeping in poll. */
/* 状态改变,唤醒等待的进程 */
sk->sk_state_change(sk);
release_sock(sk);
return err;
}

tcp层shutdown实现请移步下面文章<TCP层shutdown系统调用的实现分析>;

05-19 06:28