|
@@ -487,8 +487,8 @@ static int unix_socketpair(struct socket *, struct socket *);
|
|
static int unix_accept(struct socket *, struct socket *, int);
|
|
static int unix_accept(struct socket *, struct socket *, int);
|
|
static int unix_getname(struct socket *, struct sockaddr *, int *, int);
|
|
static int unix_getname(struct socket *, struct sockaddr *, int *, int);
|
|
static unsigned int unix_poll(struct file *, struct socket *, poll_table *);
|
|
static unsigned int unix_poll(struct file *, struct socket *, poll_table *);
|
|
-static unsigned int unix_datagram_poll(struct file *, struct socket *,
|
|
|
|
- poll_table *);
|
|
|
|
|
|
+static unsigned int unix_dgram_poll(struct file *, struct socket *,
|
|
|
|
+ poll_table *);
|
|
static int unix_ioctl(struct socket *, unsigned int, unsigned long);
|
|
static int unix_ioctl(struct socket *, unsigned int, unsigned long);
|
|
static int unix_shutdown(struct socket *, int);
|
|
static int unix_shutdown(struct socket *, int);
|
|
static int unix_stream_sendmsg(struct kiocb *, struct socket *,
|
|
static int unix_stream_sendmsg(struct kiocb *, struct socket *,
|
|
@@ -534,7 +534,7 @@ static const struct proto_ops unix_dgram_ops = {
|
|
.socketpair = unix_socketpair,
|
|
.socketpair = unix_socketpair,
|
|
.accept = sock_no_accept,
|
|
.accept = sock_no_accept,
|
|
.getname = unix_getname,
|
|
.getname = unix_getname,
|
|
- .poll = unix_datagram_poll,
|
|
|
|
|
|
+ .poll = unix_dgram_poll,
|
|
.ioctl = unix_ioctl,
|
|
.ioctl = unix_ioctl,
|
|
.listen = sock_no_listen,
|
|
.listen = sock_no_listen,
|
|
.shutdown = unix_shutdown,
|
|
.shutdown = unix_shutdown,
|
|
@@ -555,7 +555,7 @@ static const struct proto_ops unix_seqpacket_ops = {
|
|
.socketpair = unix_socketpair,
|
|
.socketpair = unix_socketpair,
|
|
.accept = unix_accept,
|
|
.accept = unix_accept,
|
|
.getname = unix_getname,
|
|
.getname = unix_getname,
|
|
- .poll = unix_datagram_poll,
|
|
|
|
|
|
+ .poll = unix_dgram_poll,
|
|
.ioctl = unix_ioctl,
|
|
.ioctl = unix_ioctl,
|
|
.listen = unix_listen,
|
|
.listen = unix_listen,
|
|
.shutdown = unix_shutdown,
|
|
.shutdown = unix_shutdown,
|
|
@@ -1994,29 +1994,13 @@ static unsigned int unix_poll(struct file * file, struct socket *sock, poll_tabl
|
|
return mask;
|
|
return mask;
|
|
}
|
|
}
|
|
|
|
|
|
-static unsigned int unix_datagram_poll(struct file *file, struct socket *sock,
|
|
|
|
- poll_table *wait)
|
|
|
|
|
|
+static unsigned int unix_dgram_poll(struct file *file, struct socket *sock,
|
|
|
|
+ poll_table *wait)
|
|
{
|
|
{
|
|
- struct sock *sk = sock->sk, *peer;
|
|
|
|
- unsigned int mask;
|
|
|
|
|
|
+ struct sock *sk = sock->sk, *other;
|
|
|
|
+ unsigned int mask, writable;
|
|
|
|
|
|
poll_wait(file, sk->sk_sleep, wait);
|
|
poll_wait(file, sk->sk_sleep, wait);
|
|
-
|
|
|
|
- peer = unix_peer_get(sk);
|
|
|
|
- if (peer) {
|
|
|
|
- if (peer != sk) {
|
|
|
|
- /*
|
|
|
|
- * Writability of a connected socket additionally
|
|
|
|
- * depends on the state of the receive queue of the
|
|
|
|
- * peer.
|
|
|
|
- */
|
|
|
|
- poll_wait(file, &unix_sk(peer)->peer_wait, wait);
|
|
|
|
- } else {
|
|
|
|
- sock_put(peer);
|
|
|
|
- peer = NULL;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
mask = 0;
|
|
mask = 0;
|
|
|
|
|
|
/* exceptional events? */
|
|
/* exceptional events? */
|
|
@@ -2042,14 +2026,26 @@ static unsigned int unix_datagram_poll(struct file *file, struct socket *sock,
|
|
}
|
|
}
|
|
|
|
|
|
/* writable? */
|
|
/* writable? */
|
|
- if (unix_writable(sk) && !(peer && unix_recvq_full(peer)))
|
|
|
|
|
|
+ writable = unix_writable(sk);
|
|
|
|
+ if (writable) {
|
|
|
|
+ other = unix_peer_get(sk);
|
|
|
|
+ if (other) {
|
|
|
|
+ if (unix_peer(other) != sk) {
|
|
|
|
+ poll_wait(file, &unix_sk(other)->peer_wait,
|
|
|
|
+ wait);
|
|
|
|
+ if (unix_recvq_full(other))
|
|
|
|
+ writable = 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ sock_put(other);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (writable)
|
|
mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
|
|
mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
|
|
else
|
|
else
|
|
set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
|
|
set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
|
|
|
|
|
|
- if (peer)
|
|
|
|
- sock_put(peer);
|
|
|
|
-
|
|
|
|
return mask;
|
|
return mask;
|
|
}
|
|
}
|
|
|
|
|