patch-2.4.0-test7 linux/net/unix/af_unix.c
Next file: linux/scripts/Menuconfig
Previous file: linux/net/sunrpc/sched.c
Back to the patch index
Back to the overall index
- Lines: 91
- Date:
Fri Aug 18 10:26:25 2000
- Orig file:
v2.4.0-test6/linux/net/unix/af_unix.c
- Orig date:
Wed Aug 9 19:19:52 2000
diff -u --recursive --new-file v2.4.0-test6/linux/net/unix/af_unix.c linux/net/unix/af_unix.c
@@ -8,7 +8,7 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
- * Version: $Id: af_unix.c,v 1.102 2000/07/26 01:04:21 davem Exp $
+ * Version: $Id: af_unix.c,v 1.105 2000/08/16 10:58:22 davem Exp $
*
* Fixes:
* Linus Torvalds : Assorted bug cures.
@@ -306,6 +306,27 @@
read_unlock(&sk->callback_lock);
}
+/* When dgram socket disconnects (or changes its peer), we clear its receive
+ * queue of packets arrived from previous peer. First, it allows to do
+ * flow control based only on wmem_alloc; second, sk connected to peer
+ * may receive messages only from that peer. */
+static void unix_dgram_disconnected(struct sock *sk, struct sock *other)
+{
+ if (skb_queue_len(&sk->receive_queue)) {
+ skb_queue_purge(&sk->receive_queue);
+ wake_up_interruptible_all(&sk->protinfo.af_unix.peer_wait);
+
+ /* If one link of bidirectional dgram pipe is disconnected,
+ * we signal error. Messages are lost. Do not make this,
+ * when peer was not connected to us.
+ */
+ if (!other->dead && unix_peer(other) == sk) {
+ other->err = ECONNRESET;
+ other->error_report(other);
+ }
+ }
+}
+
static void unix_sock_destructor(struct sock *sk)
{
skb_queue_purge(&sk->receive_queue);
@@ -572,7 +593,8 @@
int err = 0;
if (sunname->sun_path[0]) {
- if (path_init(sunname->sun_path, LOOKUP_POSITIVE, &nd))
+ if (path_init(sunname->sun_path,
+ LOOKUP_POSITIVE|LOOKUP_FOLLOW, &nd))
err = path_walk(sunname->sun_path, &nd);
if (err)
goto fail;
@@ -788,6 +810,8 @@
unix_peer(sk)=other;
unix_state_wunlock(sk);
+ if (other != old_peer)
+ unix_dgram_disconnected(sk, old_peer);
sock_put(old_peer);
} else {
unix_peer(sk)=other;
@@ -1203,6 +1227,7 @@
unix_peer(sk)=NULL;
unix_state_wunlock(sk);
+ unix_dgram_disconnected(sk, other);
sock_put(other);
err = -ECONNREFUSED;
} else {
@@ -1219,7 +1244,8 @@
if (other->shutdown&RCV_SHUTDOWN)
goto out_unlock;
- if (skb_queue_len(&other->receive_queue) > other->max_ack_backlog) {
+ if (unix_peer(other) != sk &&
+ skb_queue_len(&other->receive_queue) > other->max_ack_backlog) {
if (!timeo) {
err = -EAGAIN;
goto out_unlock;
@@ -1640,7 +1666,6 @@
return 0;
}
-
static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
struct sock *sk = sock->sk;
@@ -1736,7 +1761,7 @@
s->socket ?
(s->state == TCP_ESTABLISHED ? SS_CONNECTED : SS_UNCONNECTED) :
(s->state == TCP_ESTABLISHED ? SS_CONNECTING : SS_DISCONNECTING),
- s->socket ? s->socket->inode->i_ino : 0);
+ sock_i_ino(s));
if (s->protinfo.af_unix.addr)
{
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)