* bpfread - read next chunk of packets from buffers */
| 976 | * bpfread - read next chunk of packets from buffers |
| 977 | */ |
| 978 | static int |
| 979 | bpfread(struct cdev *dev, struct uio *uio, int ioflag) |
| 980 | { |
| 981 | struct bpf_d *d; |
| 982 | int error; |
| 983 | int non_block; |
| 984 | int timed_out; |
| 985 | |
| 986 | error = devfs_get_cdevpriv((void **)&d); |
| 987 | if (error != 0) |
| 988 | return (error); |
| 989 | |
| 990 | /* |
| 991 | * Restrict application to use a buffer the same size as |
| 992 | * as kernel buffers. |
| 993 | */ |
| 994 | if (uio->uio_resid != d->bd_bufsize) |
| 995 | return (EINVAL); |
| 996 | |
| 997 | non_block = ((ioflag & O_NONBLOCK) != 0); |
| 998 | |
| 999 | BPFD_LOCK(d); |
| 1000 | BPF_PID_REFRESH_CUR(d); |
| 1001 | if (d->bd_bufmode != BPF_BUFMODE_BUFFER) { |
| 1002 | BPFD_UNLOCK(d); |
| 1003 | return (EOPNOTSUPP); |
| 1004 | } |
| 1005 | if (d->bd_state == BPF_WAITING) |
| 1006 | callout_stop(&d->bd_callout); |
| 1007 | timed_out = (d->bd_state == BPF_TIMED_OUT); |
| 1008 | d->bd_state = BPF_IDLE; |
| 1009 | while (d->bd_hbuf_in_use) { |
| 1010 | error = mtx_sleep(&d->bd_hbuf_in_use, &d->bd_lock, |
| 1011 | PRINET|PCATCH, "bd_hbuf", 0); |
| 1012 | if (error != 0) { |
| 1013 | BPFD_UNLOCK(d); |
| 1014 | return (error); |
| 1015 | } |
| 1016 | } |
| 1017 | /* |
| 1018 | * If the hold buffer is empty, then do a timed sleep, which |
| 1019 | * ends when the timeout expires or when enough packets |
| 1020 | * have arrived to fill the store buffer. |
| 1021 | */ |
| 1022 | while (d->bd_hbuf == NULL) { |
| 1023 | if (d->bd_slen != 0) { |
| 1024 | /* |
| 1025 | * A packet(s) either arrived since the previous |
| 1026 | * read or arrived while we were asleep. |
| 1027 | */ |
| 1028 | if (d->bd_immediate || non_block || timed_out) { |
| 1029 | /* |
| 1030 | * Rotate the buffers and return what's here |
| 1031 | * if we are in immediate mode, non-blocking |
| 1032 | * flag is set, or this descriptor timed out. |
| 1033 | */ |
| 1034 | ROTATE_BUFFERS(d); |
| 1035 | break; |
nothing calls this directly
no test coverage detected