copied = skb->len; if (copied > size) copied = size; rc = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); if (rc) goto dgram_free; if (skb->len > copied) { skb_pull(skb, copied); skb_queue_head(&sk->sk_receive_queue, skb); } if (uaddr) memcpy(uaddr, llc_ui_skb_cb(skb), sizeof(*uaddr)); msg->msg_namelen = sizeof(*uaddr); if (!skb->next) { dgram_free: kfree_skb(skb); } 
 timeo = sock_rcvtimeo(sk, nonblock);  seq = &llc->copied_seq; if (flags & MSG_PEEK) { peek_seq = llc->copied_seq; seq = &peek_seq; }  target = sock_rcvlowat(sk, flags & MSG_WAITALL, len); copied = 0;  do { u32 offset;  /* * We need to check signals first, to get correct SIGURG * handling. FIXME: Need to check this doesn't impact 1003.1g * and move it down to the bottom of the loop */ if (signal_pending(current)) { if (copied) break; copied = timeo ? sock_intr_errno(timeo) : -EAGAIN; break; }  /* Next get a buffer. */  skb = skb_peek(&sk->sk_receive_queue); if (skb) { offset = *seq; goto found_ok_skb; } /* Well, if we have backlog, try to process it now yet. */  if (copied >= target && !sk->sk_backlog.tail) break;  if (copied) { if (sk->sk_err || sk->sk_state == TCP_CLOSE || (sk->sk_shutdown & RCV_SHUTDOWN) || !timeo || (flags & MSG_PEEK)) break; } else { if (sock_flag(sk, SOCK_DONE)) break;  if (sk->sk_err) { copied = sock_error(sk); break; } if (sk->sk_shutdown & RCV_SHUTDOWN) break;  if (sk->sk_state == TCP_CLOSE) { if (!sock_flag(sk, SOCK_DONE)) { /* * This occurs when user tries to read * from never connected socket. */ copied = -ENOTCONN; break; } break; } if (!timeo) { copied = -EAGAIN; break; } }  if (copied >= target) { /* Do not sleep, just process backlog. */ release_sock(sk); lock_sock(sk); } else sk_wait_data(sk, &timeo);  if ((flags & MSG_PEEK) && peek_seq != llc->copied_seq) { if (net_ratelimit()) printk(KERN_DEBUG "LLC(%s:%d): Application " "bug, race in MSG_PEEK.\n", current->comm, current->pid); peek_seq = llc->copied_seq; } continue; found_ok_skb: /* Ok so how much can we use? */ used = skb->len - offset; if (len < used) used = len;  if (!(flags & MSG_TRUNC)) { int rc = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, used); if (rc) { /* Exception. Bailout! */ if (!copied) copied = -EFAULT; break; } }  *seq += used; copied += used; len -= used;  if (used + offset < skb->len) continue;  if (!(flags & MSG_PEEK)) { sk_eat_skb(sk, skb); *seq = 0; } } while (len > 0);  /* * According to UNIX98, msg_name/msg_namelen are ignored * on connected socket. -ANK * But... af_llc still doesn't have separate sets of methods for * SOCK_DGRAM and SOCK_STREAM :-( So we have to do this test, will * eventually fix this tho :-) -acme */ if (sk->sk_type == SOCK_DGRAM) goto copy_uaddr; 
static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,			  struct msghdr *msg, size_t size, int flags){	struct sock *sk = sock->sk;	struct sockaddr_llc *uaddr = (struct sockaddr_llc *)msg->msg_name;	struct sk_buff *skb;	size_t copied = 0;	int rc = -ENOMEM;	int noblock = flags & MSG_DONTWAIT;	dprintk("%s: receiving in %02X from %02X\n", __FUNCTION__,		llc_sk(sk)->laddr.lsap, llc_sk(sk)->daddr.lsap);	lock_sock(sk);	if (skb_queue_empty(&sk->sk_receive_queue)) {		rc = llc_wait_data(sk, sock_rcvtimeo(sk, noblock));		if (rc)			goto out;	}	skb = skb_dequeue(&sk->sk_receive_queue);	if (!skb) /* shutdown */		goto out;	copied = skb->len;	if (copied > size)		copied = size;	rc = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);	if (rc)		goto dgram_free;	if (skb->len > copied) {		skb_pull(skb, copied);		skb_queue_head(&sk->sk_receive_queue, skb);	}	if (uaddr)		memcpy(uaddr, llc_ui_skb_cb(skb), sizeof(*uaddr));	msg->msg_namelen = sizeof(*uaddr);	if (!skb->next) {dgram_free:		kfree_skb(skb);	}out:	release_sock(sk);	return rc ? : copied;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/8420e1b541fe92aee1d8d4d25d9e33eaca756a7b/af_llc.c/buggy/net/llc/af_llc.c