patch-1.3.39 linux/net/unix/af_unix.c
Next file: linux/scripts/Makefile
Previous file: linux/net/netlink.c
Back to the patch index
Back to the overall index
- Lines: 126
- Date:
Thu Nov 9 09:12:14 1995
- Orig file:
v1.3.38/linux/net/unix/af_unix.c
- Orig date:
Wed Nov 8 07:11:47 1995
diff -u --recursive --new-file v1.3.38/linux/net/unix/af_unix.c linux/net/unix/af_unix.c
@@ -796,6 +796,20 @@
}
return sent;
}
+
+/*
+ * Sleep until data has arrive. But check for races..
+ */
+static void unix_data_wait(unix_socket * sk)
+{
+ cli();
+ if (!skb_peek(&sk->receive_queue)) {
+ sk->socket->flags |= SO_WAITDATA;
+ interruptible_sleep_on(sk->sleep);
+ sk->socket->flags &= ~SO_WAITDATA;
+ }
+ sti();
+}
static int unix_recvmsg(struct socket *sock, struct msghdr *msg, int size, int noblock, int flags, int *addr_len)
{
@@ -818,10 +832,7 @@
if(sk->err)
return sock_error(sk);
-/* printk("get rcv sem\n");*/
down(&sk->protinfo.af_unix.readsem); /* Lock the socket */
-/* printk("got rcv sem\n");*/
-
while(ct--)
{
int done=0;
@@ -831,42 +842,23 @@
while(done<len)
{
- if(copied & (flags&MSG_PEEK))
- {
- up(&sk->protinfo.af_unix.readsem);
- return copied;
- }
- cli();
- skb=skb_peek(&sk->receive_queue);
+ if (copied && (flags & MSG_PEEK))
+ goto out;
+ if (copied == size)
+ goto out;
+ skb=skb_dequeue(&sk->receive_queue);
if(skb==NULL)
{
up(&sk->protinfo.af_unix.readsem);
if(sk->shutdown & RCV_SHUTDOWN)
- {
- sti();
return copied;
- }
if(copied)
- {
- sti();
return copied;
- }
if(noblock)
- {
- sti();
return -EAGAIN;
- }
- sk->socket->flags |= SO_WAITDATA;
- interruptible_sleep_on(sk->sleep);
- sk->socket->flags &= ~SO_WAITDATA;
- if( current->signal & ~current->blocked)
- {
- sti();
- if(copied)
- return copied;
+ if(current->signal & ~current->blocked)
return -ERESTARTSYS;
- }
- sti();
+ unix_data_wait(sk);
down(&sk->protinfo.af_unix.readsem);
continue;
}
@@ -884,29 +876,23 @@
*addr_len=sizeof(short);
}
num=min(skb->len,size-copied);
+ memcpy_tofs(sp, skb->data, num);
copied+=num;
done+=num;
- if(flags&MSG_PEEK)
- {
- memcpy_tofs(sp, skb->data, num);
- break;
- }
- else
- {
- memcpy_tofs(sp, skb->data,num);
- skb_pull(skb,num);
- sp+=num;
- if(skb->len==0)
- {
- skb_unlink(skb);
- kfree_skb(skb, FREE_WRITE);
- if(sock->type==SOCK_DGRAM)
- break;
- }
+ sp+=num;
+ if (!(flags & MSG_PEEK))
+ skb_pull(skb, num);
+ /* put the skb back if we didn't use it up.. */
+ if (skb->len) {
+ skb_queue_head(&sk->receive_queue, skb);
+ continue;
}
- sti();
- }
- }
+ kfree_skb(skb, FREE_WRITE);
+ if(sock->type==SOCK_DGRAM)
+ goto out;
+ }
+ }
+out:
up(&sk->protinfo.af_unix.readsem);
return copied;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this