diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/unix/af_unix.c | 60 |
1 files changed, 31 insertions, 29 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 8d9bbba345a4..d8d98d5b508c 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
| @@ -1984,36 +1984,38 @@ static int unix_shutdown(struct socket *sock, int mode) | |||
| 1984 | 1984 | ||
| 1985 | mode = (mode+1)&(RCV_SHUTDOWN|SEND_SHUTDOWN); | 1985 | mode = (mode+1)&(RCV_SHUTDOWN|SEND_SHUTDOWN); |
| 1986 | 1986 | ||
| 1987 | if (mode) { | 1987 | if (!mode) |
| 1988 | unix_state_lock(sk); | 1988 | return 0; |
| 1989 | sk->sk_shutdown |= mode; | 1989 | |
| 1990 | other = unix_peer(sk); | 1990 | unix_state_lock(sk); |
| 1991 | if (other) | 1991 | sk->sk_shutdown |= mode; |
| 1992 | sock_hold(other); | 1992 | other = unix_peer(sk); |
| 1993 | unix_state_unlock(sk); | 1993 | if (other) |
| 1994 | sk->sk_state_change(sk); | 1994 | sock_hold(other); |
| 1995 | 1995 | unix_state_unlock(sk); | |
| 1996 | if (other && | 1996 | sk->sk_state_change(sk); |
| 1997 | (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET)) { | 1997 | |
| 1998 | 1998 | if (other && | |
| 1999 | int peer_mode = 0; | 1999 | (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET)) { |
| 2000 | 2000 | ||
| 2001 | if (mode&RCV_SHUTDOWN) | 2001 | int peer_mode = 0; |
| 2002 | peer_mode |= SEND_SHUTDOWN; | 2002 | |
| 2003 | if (mode&SEND_SHUTDOWN) | 2003 | if (mode&RCV_SHUTDOWN) |
| 2004 | peer_mode |= RCV_SHUTDOWN; | 2004 | peer_mode |= SEND_SHUTDOWN; |
| 2005 | unix_state_lock(other); | 2005 | if (mode&SEND_SHUTDOWN) |
| 2006 | other->sk_shutdown |= peer_mode; | 2006 | peer_mode |= RCV_SHUTDOWN; |
| 2007 | unix_state_unlock(other); | 2007 | unix_state_lock(other); |
| 2008 | other->sk_state_change(other); | 2008 | other->sk_shutdown |= peer_mode; |
| 2009 | if (peer_mode == SHUTDOWN_MASK) | 2009 | unix_state_unlock(other); |
| 2010 | sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP); | 2010 | other->sk_state_change(other); |
| 2011 | else if (peer_mode & RCV_SHUTDOWN) | 2011 | if (peer_mode == SHUTDOWN_MASK) |
| 2012 | sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN); | 2012 | sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP); |
| 2013 | } | 2013 | else if (peer_mode & RCV_SHUTDOWN) |
| 2014 | if (other) | 2014 | sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN); |
| 2015 | sock_put(other); | ||
| 2016 | } | 2015 | } |
| 2016 | if (other) | ||
| 2017 | sock_put(other); | ||
| 2018 | |||
| 2017 | return 0; | 2019 | return 0; |
| 2018 | } | 2020 | } |
| 2019 | 2021 | ||
