From a953b2df95d5b8afe53c9bcabbce199b281cb055 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Mon, 22 Mar 2010 20:26:52 +0000 Subject: MFC: r204105 Return partially filled buffer for non-blocking read(2) in non-immediate mode. PR: kern/143855 Submitted by: Guy Harris (guy at alum dot mit dot edu) --- sys/net/bpf.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'sys') diff --git a/sys/net/bpf.c b/sys/net/bpf.c index f5dc29f6a8ec..49e527def22c 100644 --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -456,8 +456,9 @@ static int bpfread(struct cdev *dev, struct uio *uio, int ioflag) { struct bpf_d *d = dev->si_drv1; - int timed_out; int error; + int non_block; + int timed_out; /* * Restrict application to use a buffer the same size as @@ -466,6 +467,8 @@ bpfread(struct cdev *dev, struct uio *uio, int ioflag) if (uio->uio_resid != d->bd_bufsize) return (EINVAL); + non_block = ((ioflag & O_NONBLOCK) != 0); + BPFD_LOCK(d); d->bd_pid = curthread->td_proc->p_pid; if (d->bd_state == BPF_WAITING) @@ -478,14 +481,20 @@ bpfread(struct cdev *dev, struct uio *uio, int ioflag) * have arrived to fill the store buffer. */ while (d->bd_hbuf == NULL) { - if ((d->bd_immediate || timed_out) && d->bd_slen != 0) { + if (d->bd_slen != 0) { /* * A packet(s) either arrived since the previous * read or arrived while we were asleep. - * Rotate the buffers and return what's here. */ - ROTATE_BUFFERS(d); - break; + if (d->bd_immediate || non_block || timed_out) { + /* + * Rotate the buffers and return what's here + * if we are in immediate mode, non-blocking + * flag is set, or this descriptor timed out. + */ + ROTATE_BUFFERS(d); + break; + } } /* @@ -499,7 +508,7 @@ bpfread(struct cdev *dev, struct uio *uio, int ioflag) return (ENXIO); } - if (ioflag & O_NONBLOCK) { + if (non_block) { BPFD_UNLOCK(d); return (EWOULDBLOCK); } -- cgit v1.3