diff options
-rw-r--r-- | net/ipx/af_ipx.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index 00b2a6d1c009..41e4e93cb3aa 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c | |||
@@ -1368,6 +1368,7 @@ static int ipx_release(struct socket *sock) | |||
1368 | goto out; | 1368 | goto out; |
1369 | 1369 | ||
1370 | lock_sock(sk); | 1370 | lock_sock(sk); |
1371 | sk->sk_shutdown = SHUTDOWN_MASK; | ||
1371 | if (!sock_flag(sk, SOCK_DEAD)) | 1372 | if (!sock_flag(sk, SOCK_DEAD)) |
1372 | sk->sk_state_change(sk); | 1373 | sk->sk_state_change(sk); |
1373 | 1374 | ||
@@ -1791,8 +1792,11 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1791 | 1792 | ||
1792 | skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, | 1793 | skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, |
1793 | flags & MSG_DONTWAIT, &rc); | 1794 | flags & MSG_DONTWAIT, &rc); |
1794 | if (!skb) | 1795 | if (!skb) { |
1796 | if (rc == -EAGAIN && (sk->sk_shutdown & RCV_SHUTDOWN)) | ||
1797 | rc = 0; | ||
1795 | goto out; | 1798 | goto out; |
1799 | } | ||
1796 | 1800 | ||
1797 | ipx = ipx_hdr(skb); | 1801 | ipx = ipx_hdr(skb); |
1798 | copied = ntohs(ipx->ipx_pktsize) - sizeof(struct ipxhdr); | 1802 | 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 | |||
1922 | } | 1926 | } |
1923 | #endif | 1927 | #endif |
1924 | 1928 | ||
1929 | static int ipx_shutdown(struct socket *sock, int mode) | ||
1930 | { | ||
1931 | struct sock *sk = sock->sk; | ||
1932 | |||
1933 | if (mode < SHUT_RD || mode > SHUT_RDWR) | ||
1934 | return -EINVAL; | ||
1935 | /* This maps: | ||
1936 | * SHUT_RD (0) -> RCV_SHUTDOWN (1) | ||
1937 | * SHUT_WR (1) -> SEND_SHUTDOWN (2) | ||
1938 | * SHUT_RDWR (2) -> SHUTDOWN_MASK (3) | ||
1939 | */ | ||
1940 | ++mode; | ||
1941 | |||
1942 | lock_sock(sk); | ||
1943 | sk->sk_shutdown |= mode; | ||
1944 | release_sock(sk); | ||
1945 | sk->sk_state_change(sk); | ||
1946 | |||
1947 | return 0; | ||
1948 | } | ||
1925 | 1949 | ||
1926 | /* | 1950 | /* |
1927 | * Socket family declarations | 1951 | * Socket family declarations |
@@ -1948,7 +1972,7 @@ static const struct proto_ops ipx_dgram_ops = { | |||
1948 | .compat_ioctl = ipx_compat_ioctl, | 1972 | .compat_ioctl = ipx_compat_ioctl, |
1949 | #endif | 1973 | #endif |
1950 | .listen = sock_no_listen, | 1974 | .listen = sock_no_listen, |
1951 | .shutdown = sock_no_shutdown, /* FIXME: support shutdown */ | 1975 | .shutdown = ipx_shutdown, |
1952 | .setsockopt = ipx_setsockopt, | 1976 | .setsockopt = ipx_setsockopt, |
1953 | .getsockopt = ipx_getsockopt, | 1977 | .getsockopt = ipx_getsockopt, |
1954 | .sendmsg = ipx_sendmsg, | 1978 | .sendmsg = ipx_sendmsg, |