提交 8815cbd9 编写于 作者: S Sabrina Dubroca 提交者: David S. Miller

ipx: implement shutdown()

IPX doesn't implement shutdown, which poses a problem to some users:

https://bugzilla.kernel.org/show_bug.cgi?id=67841

This patch is heavily based on the shutdown implementation for unix
sockets.
Reported-by: NBruno Jesus <00cpxxx@gmail.com>
Signed-off-by: NSabrina Dubroca <sd@queasysnail.net>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 6028323b
......@@ -1368,6 +1368,7 @@ static int ipx_release(struct socket *sock)
goto out;
lock_sock(sk);
sk->sk_shutdown = SHUTDOWN_MASK;
if (!sock_flag(sk, SOCK_DEAD))
sk->sk_state_change(sk);
......@@ -1791,8 +1792,11 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
flags & MSG_DONTWAIT, &rc);
if (!skb)
if (!skb) {
if (rc == -EAGAIN && (sk->sk_shutdown & RCV_SHUTDOWN))
rc = 0;
goto out;
}
ipx = ipx_hdr(skb);
copied = ntohs(ipx->ipx_pktsize) - sizeof(struct ipxhdr);
......@@ -1922,6 +1926,26 @@ static int ipx_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long
}
#endif
static int ipx_shutdown(struct socket *sock, int mode)
{
struct sock *sk = sock->sk;
if (mode < SHUT_RD || mode > SHUT_RDWR)
return -EINVAL;
/* This maps:
* SHUT_RD (0) -> RCV_SHUTDOWN (1)
* SHUT_WR (1) -> SEND_SHUTDOWN (2)
* SHUT_RDWR (2) -> SHUTDOWN_MASK (3)
*/
++mode;
lock_sock(sk);
sk->sk_shutdown |= mode;
release_sock(sk);
sk->sk_state_change(sk);
return 0;
}
/*
* Socket family declarations
......@@ -1948,7 +1972,7 @@ static const struct proto_ops ipx_dgram_ops = {
.compat_ioctl = ipx_compat_ioctl,
#endif
.listen = sock_no_listen,
.shutdown = sock_no_shutdown, /* FIXME: support shutdown */
.shutdown = ipx_shutdown,
.setsockopt = ipx_setsockopt,
.getsockopt = ipx_getsockopt,
.sendmsg = ipx_sendmsg,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册