+
+ if (kn->kn_filter != EVFILT_READ) {
+ return (EINVAL);
+ }
+
+ lck_mtx_lock(bpf_mlock);
+
+ d = bpf_dtab[minor(dev)];
+ if (d == 0 || d == (void *)1 || (d->bd_flags & BPF_CLOSING) != 0) {
+ lck_mtx_unlock(bpf_mlock);
+ return (ENXIO);
+ }
+
+ if (d->bd_bif == NULL) {
+ lck_mtx_unlock(bpf_mlock);
+ return (ENXIO);
+ }
+
+ kn->kn_hook = d;
+ kn->kn_fop = &bpfread_filtops;
+ KNOTE_ATTACH(&d->bd_sel.si_note, kn);
+ d->bd_flags |= BPF_KNOTE;
+
+ lck_mtx_unlock(bpf_mlock);
+ return (0);
+}
+
+static void
+filt_bpfdetach(struct knote *kn)
+{
+ struct bpf_d *d = (struct bpf_d *)kn->kn_hook;
+
+ lck_mtx_lock(bpf_mlock);
+ if (d->bd_flags & BPF_KNOTE) {
+ KNOTE_DETACH(&d->bd_sel.si_note, kn);
+ d->bd_flags &= ~BPF_KNOTE;
+ }
+ lck_mtx_unlock(bpf_mlock);
+}
+
+static int
+filt_bpfread(struct knote *kn, long hint)
+{
+ struct bpf_d *d = (struct bpf_d *)kn->kn_hook;
+ int ready = 0;
+
+ if (hint == 0)
+ lck_mtx_lock(bpf_mlock);
+
+ if (d->bd_immediate) {
+ /*
+ * If there's data in the hold buffer, it's the
+ * amount of data a read will return.
+ *
+ * If there's no data in the hold buffer, but
+ * there's data in the store buffer, a read will
+ * immediately rotate the store buffer to the
+ * hold buffer, the amount of data in the store
+ * buffer is the amount of data a read will
+ * return.
+ *
+ * If there's no data in either buffer, we're not
+ * ready to read.
+ */
+ kn->kn_data = ((d->bd_hlen == 0 || d->bd_hbuf_read)
+ ? d->bd_slen : d->bd_hlen);
+ int64_t lowwat = 1;
+ if (kn->kn_sfflags & NOTE_LOWAT)
+ {
+ if (kn->kn_sdata > d->bd_bufsize)
+ lowwat = d->bd_bufsize;
+ else if (kn->kn_sdata > lowwat)
+ lowwat = kn->kn_sdata;
+ }
+ ready = (kn->kn_data >= lowwat);
+ } else {
+ /*
+ * If there's data in the hold buffer, it's the
+ * amount of data a read will return.
+ *
+ * If there's no data in the hold buffer, but
+ * there's data in the store buffer, if the
+ * timer has expired a read will immediately
+ * rotate the store buffer to the hold buffer,
+ * so the amount of data in the store buffer is
+ * the amount of data a read will return.
+ *
+ * If there's no data in either buffer, or there's
+ * no data in the hold buffer and the timer hasn't
+ * expired, we're not ready to read.
+ */
+ kn->kn_data = ((d->bd_hlen == 0 || d->bd_hbuf_read) && d->bd_state == BPF_TIMED_OUT ?
+ d->bd_slen : d->bd_hlen);
+ ready = (kn->kn_data > 0);
+ }
+ if (!ready)
+ bpf_start_timer(d);
+
+ if (hint == 0)
+ lck_mtx_unlock(bpf_mlock);
+ return (ready);