summaryrefslogtreecommitdiffstats
path: root/sys/net/bpf.c
diff options
context:
space:
mode:
authorjkim <jkim@FreeBSD.org>2010-02-20 00:19:21 +0000
committerjkim <jkim@FreeBSD.org>2010-02-20 00:19:21 +0000
commit30767ce70baeb3b458edf7df558973143c661bc5 (patch)
treeb84857790f964cf6166d0be8b3b6043200489a97 /sys/net/bpf.c
parent1650c19704013ae8f5d8181ff3b0f1a6aceebddc (diff)
downloadFreeBSD-src-30767ce70baeb3b458edf7df558973143c661bc5.zip
FreeBSD-src-30767ce70baeb3b458edf7df558973143c661bc5.tar.gz
Return partially filled buffer for non-blocking read(2)
in non-immediate mode. PR: kern/143855
Diffstat (limited to 'sys/net/bpf.c')
-rw-r--r--sys/net/bpf.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index f6260c0..65e3f2b 100644
--- a/sys/net/bpf.c
+++ b/sys/net/bpf.c
@@ -664,8 +664,9 @@ static int
bpfread(struct cdev *dev, struct uio *uio, int ioflag)
{
struct bpf_d *d;
- int timed_out;
int error;
+ int non_block;
+ int timed_out;
error = devfs_get_cdevpriv((void **)&d);
if (error != 0)
@@ -678,6 +679,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_bufmode != BPF_BUFMODE_BUFFER) {
@@ -694,14 +697,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;
+ }
}
/*
@@ -715,7 +724,7 @@ bpfread(struct cdev *dev, struct uio *uio, int ioflag)
return (ENXIO);
}
- if (ioflag & O_NONBLOCK) {
+ if (non_block) {
BPFD_UNLOCK(d);
return (EWOULDBLOCK);
}
OpenPOWER on IntegriCloud