diff options
author | jlemon <jlemon@FreeBSD.org> | 2000-04-16 18:53:38 +0000 |
---|---|---|
committer | jlemon <jlemon@FreeBSD.org> | 2000-04-16 18:53:38 +0000 |
commit | c41c876463ee8c302f06554537e0fb22a3fcdca4 (patch) | |
tree | d2f87a6af04c4f35f243bf580d099496a4131330 /sys/fs | |
parent | f8f9ad64d408b963d98d0e11b37e871763557e95 (diff) | |
download | FreeBSD-src-c41c876463ee8c302f06554537e0fb22a3fcdca4.zip FreeBSD-src-c41c876463ee8c302f06554537e0fb22a3fcdca4.tar.gz |
Introduce kqueue() and kevent(), a kernel event notification facility.
Diffstat (limited to 'sys/fs')
-rw-r--r-- | sys/fs/fifofs/fifo_vnops.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/sys/fs/fifofs/fifo_vnops.c b/sys/fs/fifofs/fifo_vnops.c index b64f957..5bd13a7 100644 --- a/sys/fs/fifofs/fifo_vnops.c +++ b/sys/fs/fifofs/fifo_vnops.c @@ -46,6 +46,7 @@ #include <sys/filio.h> #include <sys/fcntl.h> #include <sys/file.h> +#include <sys/event.h> #include <sys/poll.h> #include <sys/un.h> #include <miscfs/fifofs/fifo.h> @@ -75,6 +76,17 @@ static int fifo_bmap __P((struct vop_bmap_args *)); static int fifo_pathconf __P((struct vop_pathconf_args *)); static int fifo_advlock __P((struct vop_advlock_args *)); +static int filt_fiforattach(struct knote *kn); +static void filt_fifordetach(struct knote *kn); +static int filt_fiforead(struct knote *kn, long hint); +static int filt_fifowattach(struct knote *kn); +static void filt_fifowdetach(struct knote *kn); +static int filt_fifowrite(struct knote *kn, long hint); + +struct filterops fifo_rwfiltops[] = { + { 1, filt_fiforattach, filt_fifordetach, filt_fiforead }, + { 1, filt_fifowattach, filt_fifowdetach, filt_fifowrite }, +}; vop_t **fifo_vnodeop_p; static struct vnodeopv_entry_desc fifo_vnodeop_entries[] = { @@ -343,6 +355,80 @@ fifo_ioctl(ap) return (0); } +static int +filt_fiforattach(struct knote *kn) +{ + struct vnode *vn = (struct vnode *)kn->kn_fp->f_data; + struct socket *so = (struct socket *)vn->v_fifoinfo->fi_readsock; + + SLIST_INSERT_HEAD(&so->so_rcv.sb_sel.si_note, kn, kn_selnext); + so->so_rcv.sb_flags |= SB_KNOTE; + return (0); +} + +static void +filt_fifordetach(struct knote *kn) +{ + struct vnode *vn = (struct vnode *)kn->kn_fp->f_data; + struct socket *so = (struct socket *)vn->v_fifoinfo->fi_readsock; + + SLIST_REMOVE(&so->so_rcv.sb_sel.si_note, kn, knote, kn_selnext); + if (SLIST_EMPTY(&so->so_rcv.sb_sel.si_note)) + so->so_rcv.sb_flags &= ~SB_KNOTE; +} + +static int +filt_fiforead(struct knote *kn, long hint) +{ + struct vnode *vn = (struct vnode *)kn->kn_fp->f_data; + struct socket *so = (struct socket *)vn->v_fifoinfo->fi_readsock; + + kn->kn_data = so->so_rcv.sb_cc; + if (so->so_state & SS_CANTRCVMORE) { + kn->kn_flags |= EV_EOF; + return (1); + } + kn->kn_flags &= ~EV_EOF; + return (kn->kn_data > 0); +} + +static int +filt_fifowattach(struct knote *kn) +{ + struct vnode *vn = (struct vnode *)kn->kn_fp->f_data; + struct socket *so = (struct socket *)vn->v_fifoinfo->fi_writesock; + + SLIST_INSERT_HEAD(&so->so_snd.sb_sel.si_note, kn, kn_selnext); + so->so_rcv.sb_flags |= SB_KNOTE; + return (0); +} + +static void +filt_fifowdetach(struct knote *kn) +{ + struct vnode *vn = (struct vnode *)kn->kn_fp->f_data; + struct socket *so = (struct socket *)vn->v_fifoinfo->fi_readsock; + + SLIST_REMOVE(&so->so_snd.sb_sel.si_note, kn, knote, kn_selnext); + if (SLIST_EMPTY(&so->so_snd.sb_sel.si_note)) + so->so_snd.sb_flags &= ~SB_KNOTE; +} + +static int +filt_fifowrite(struct knote *kn, long hint) +{ + struct vnode *vn = (struct vnode *)kn->kn_fp->f_data; + struct socket *so = (struct socket *)vn->v_fifoinfo->fi_readsock; + + kn->kn_data = sbspace(&so->so_snd); + if (so->so_state & SS_CANTSENDMORE) { + kn->kn_flags |= EV_EOF; + return (1); + } + kn->kn_flags &= ~EV_EOF; + return (kn->kn_data >= so->so_snd.sb_lowat); +} + /* ARGSUSED */ static int fifo_poll(ap) |