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: Bruno Jesus <00cpxxx@gmail.com> Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
6028323b52
commit
8815cbd9e3
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue