fifo_poll() honors FREAD and FWRITE. It doesn't return events incompatible with the open flags. Diff below makes the kqfilters behave like that as well.
ok? Index: kern/tty_tty.c =================================================================== RCS file: /cvs/src/sys/kern/tty_tty.c,v retrieving revision 1.24 diff -u -p -r1.24 tty_tty.c --- kern/tty_tty.c 2 May 2018 02:24:56 -0000 1.24 +++ kern/tty_tty.c 7 Apr 2020 10:36:08 -0000 @@ -160,5 +160,5 @@ cttykqfilter(dev_t dev, struct knote *kn if (ttyvp == NULL) return (ENXIO); - return (VOP_KQFILTER(ttyvp, kn)); + return (VOP_KQFILTER(ttyvp, FREAD|FWRITE, kn)); } Index: kern/vfs_vnops.c =================================================================== RCS file: /cvs/src/sys/kern/vfs_vnops.c,v retrieving revision 1.113 diff -u -p -r1.113 vfs_vnops.c --- kern/vfs_vnops.c 22 Feb 2020 11:58:29 -0000 1.113 +++ kern/vfs_vnops.c 7 Apr 2020 10:36:08 -0000 @@ -619,7 +619,7 @@ vn_closefile(struct file *fp, struct pro int vn_kqfilter(struct file *fp, struct knote *kn) { - return (VOP_KQFILTER(fp->f_data, kn)); + return (VOP_KQFILTER(fp->f_data, fp->f_flag, kn)); } int Index: kern/vfs_vops.c =================================================================== RCS file: /cvs/src/sys/kern/vfs_vops.c,v retrieving revision 1.27 diff -u -p -r1.27 vfs_vops.c --- kern/vfs_vops.c 31 Mar 2020 06:54:05 -0000 1.27 +++ kern/vfs_vops.c 7 Apr 2020 10:36:08 -0000 @@ -307,10 +307,11 @@ VOP_POLL(struct vnode *vp, int fflag, in } int -VOP_KQFILTER(struct vnode *vp, struct knote *kn) +VOP_KQFILTER(struct vnode *vp, int fflag, struct knote *kn) { struct vop_kqfilter_args a; a.a_vp = vp; + a.a_fflag = fflag; a.a_kn = kn; if (vp->v_op->vop_kqfilter == NULL) Index: sys/vnode.h =================================================================== RCS file: /cvs/src/sys/sys/vnode.h,v retrieving revision 1.155 diff -u -p -r1.155 vnode.h --- sys/vnode.h 20 Jan 2020 23:21:56 -0000 1.155 +++ sys/vnode.h 7 Apr 2020 10:36:08 -0000 @@ -412,9 +412,10 @@ int VOP_POLL(struct vnode *, int, int, s struct vop_kqfilter_args { struct vnode *a_vp; + int a_fflag; struct knote *a_kn; }; -int VOP_KQFILTER(struct vnode *, struct knote *); +int VOP_KQFILTER(struct vnode *, int, struct knote *); struct vop_revoke_args { struct vnode *a_vp; Index: miscfs/fifofs/fifo_vnops.c =================================================================== RCS file: /cvs/src/sys/miscfs/fifofs/fifo_vnops.c,v retrieving revision 1.73 diff -u -p -r1.73 fifo_vnops.c --- miscfs/fifofs/fifo_vnops.c 20 Feb 2020 16:56:52 -0000 1.73 +++ miscfs/fifofs/fifo_vnops.c 7 Apr 2020 10:37:42 -0000 @@ -512,10 +512,14 @@ fifo_kqfilter(void *v) switch (ap->a_kn->kn_filter) { case EVFILT_READ: + if (!(ap->a_fflag & FREAD)) + return (EINVAL); ap->a_kn->kn_fop = &fiforead_filtops; sb = &so->so_rcv; break; case EVFILT_WRITE: + if (!(ap->a_fflag & FWRITE)) + return (EINVAL); ap->a_kn->kn_fop = &fifowrite_filtops; sb = &so->so_snd; break;