diff options
author | jkim <jkim@FreeBSD.org> | 2010-02-20 00:19:21 +0000 |
---|---|---|
committer | jkim <jkim@FreeBSD.org> | 2010-02-20 00:19:21 +0000 |
commit | 30767ce70baeb3b458edf7df558973143c661bc5 (patch) | |
tree | b84857790f964cf6166d0be8b3b6043200489a97 /sys/net/bpf.c | |
parent | 1650c19704013ae8f5d8181ff3b0f1a6aceebddc (diff) | |
download | FreeBSD-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.c | 21 |
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); } |