select for UNIX sockets - 2.4 and 2.5
Subsystems (2)
PATCH 1/1 select for UNIX sockets - 2.4 and 2.5
Hi,
The attached patches aims to fix select(write) on connect()ed UNIX datagram sockets. Without this patch, such select() is basically a NOP i.e. it returns immediately indicating a datagram can be written.
As I don't know this part of the kernel very well I'd appreciate it if you who know it better check the patch for correctness.
A simple test program is attached as well.
This patch doesn't fix select(write) on unconnect()ed sockets as there is no obvious way to check for socket state.
Signature · 2 lines
Krzysztof Halasa Network Administrator
net/unix/af_unix.c +34 -1
@@ -1707,6 +1707,39 @@return err; } +static unsigned int dgram_poll (struct file * file,struct socket *sock, +poll_table *wait) +{ +struct sock *sk = sock->sk; +unsigned int mask; +unix_socket *other; + +poll_wait (file, sk->sleep, wait); + mask =0 ; + +/* exceptional events? */ +if (sk->err || !skb_queue_empty (&sk->error_queue)) + mask |=POLLERR ; +if (sk->shutdown ==SHUTDOWN_MASK ) + mask |=POLLHUP ; + +/* readable? */ +if (!skb_queue_empty (&sk->receive_queue) || + (sk->shutdown &RCV_SHUTDOWN )) + mask |=POLLIN |POLLRDNORM ; + +/* writable? */ + other =unix_peer_get (sk); +if (sock_writeable (sk) && + (other ==NULL || +skb_queue_len (&other->receive_queue) <= other->max_ack_backlog)) + mask |=POLLOUT |POLLWRNORM |POLLWRBAND ; +else +set_bit (SOCK_ASYNC_NOSPACE , &sk->socket->flags); + +return mask; +} +static unsigned int unix_poll (struct file * file,struct socket *sock,poll_table *wait) {struct sock *sk = sock->sk;
@@ -1836,7 +1869,7 @@ socketpair: unix_socketpair, accept: sock_no_accept, getname: unix_getname, - poll: datagram_poll, + poll: dgram_poll, ioctl: unix_ioctl, listen: sock_no_listen, shutdown: unix_shutdown,
net/unix/af_unix.c +34 -1
@@ -1784,6 +1784,39 @@return err; } +static unsigned int dgram_poll (struct file * file,struct socket *sock, +poll_table *wait) +{ +struct sock *sk = sock->sk; +unsigned int mask; +unix_socket *other; + +poll_wait (file, sk->sleep, wait); + mask =0 ; + +/* exceptional events? */ +if (sk->err || !skb_queue_empty (&sk->error_queue)) + mask |=POLLERR ; +if (sk->shutdown ==SHUTDOWN_MASK ) + mask |=POLLHUP ; + +/* readable? */ +if (!skb_queue_empty (&sk->receive_queue) || + (sk->shutdown &RCV_SHUTDOWN )) + mask |=POLLIN |POLLRDNORM ; + +/* writable? */ + other =unix_peer_get (sk); +if (sock_writeable (sk) && + (other ==NULL || +skb_queue_len (&other->receive_queue) <= other->max_ack_backlog)) + mask |=POLLOUT |POLLWRNORM |POLLWRBAND ; +else +set_bit (SOCK_ASYNC_NOSPACE , &sk->socket->flags); + +return mask; +} +static unsigned int unix_poll (struct file * file,struct socket *sock,poll_table *wait) {struct sock *sk = sock->sk;
@@ -1913,7 +1946,7 @@ .socketpair = unix_socketpair, .accept = sock_no_accept, .getname = unix_getname, - .poll = datagram_poll, + .poll = dgram_poll, .ioctl = unix_ioctl, .listen = sock_no_listen, .shutdown = unix_shutdown,