lkml.org 
[lkml]   [2003]   [Jun]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patches in this message
/
Subject[PATCH] select for UNIX sockets - 2.4 and 2.5
From
Date
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.
--
Krzysztof Halasa
Network Administrator
--- linux-2.4.orig/net/unix/af_unix.c 2002-11-29 00:53:16.000000000 +0100
+++ linux-2.4/net/unix/af_unix.c 2003-06-14 17:04:26.000000000 +0200
@@ -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,--- linux-2.5.orig/net/unix/af_unix.c 2003-05-27 03:00:41.000000000 +0200
+++ linux-2.5/net/unix/af_unix.c 2003-06-14 16:31:59.000000000 +0200
@@ -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,[unhandled content-type:application/octet-stream]
\
 
 \ /
  Last update: 2005-03-22 13:36    [W:0.027 / U:0.656 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site