version 1.30.4.7, 2002/09/29 09:58:15 |
version 1.31, 2001/09/22 22:35:18 |
|
|
* @(#)fifo_vnops.c 8.10 (Berkeley) 5/27/95 |
* @(#)fifo_vnops.c 8.10 (Berkeley) 5/27/95 |
*/ |
*/ |
|
|
#include <sys/cdefs.h> |
|
__KERNEL_RCSID(0, "$NetBSD$"); |
|
|
|
#include <sys/param.h> |
#include <sys/param.h> |
#include <sys/systm.h> |
#include <sys/systm.h> |
#include <sys/proc.h> |
#include <sys/proc.h> |
Line 53 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 50 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#include <sys/malloc.h> |
#include <sys/malloc.h> |
#include <sys/un.h> |
#include <sys/un.h> |
#include <sys/poll.h> |
#include <sys/poll.h> |
#include <sys/event.h> |
|
|
|
#include <miscfs/fifofs/fifo.h> |
#include <miscfs/fifofs/fifo.h> |
#include <miscfs/genfs/genfs.h> |
#include <miscfs/genfs/genfs.h> |
Line 65 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 61 __KERNEL_RCSID(0, "$NetBSD$"); |
|
struct fifoinfo { |
struct fifoinfo { |
struct socket *fi_readsock; |
struct socket *fi_readsock; |
struct socket *fi_writesock; |
struct socket *fi_writesock; |
long fi_opencount; |
|
long fi_readers; |
long fi_readers; |
long fi_writers; |
long fi_writers; |
}; |
}; |
Line 86 const struct vnodeopv_entry_desc fifo_vn |
|
Line 81 const struct vnodeopv_entry_desc fifo_vn |
|
{ &vop_lease_desc, fifo_lease_check }, /* lease */ |
{ &vop_lease_desc, fifo_lease_check }, /* lease */ |
{ &vop_ioctl_desc, fifo_ioctl }, /* ioctl */ |
{ &vop_ioctl_desc, fifo_ioctl }, /* ioctl */ |
{ &vop_poll_desc, fifo_poll }, /* poll */ |
{ &vop_poll_desc, fifo_poll }, /* poll */ |
{ &vop_kqfilter_desc, fifo_kqfilter }, /* kqfilter */ |
|
{ &vop_revoke_desc, fifo_revoke }, /* revoke */ |
{ &vop_revoke_desc, fifo_revoke }, /* revoke */ |
{ &vop_mmap_desc, fifo_mmap }, /* mmap */ |
{ &vop_mmap_desc, fifo_mmap }, /* mmap */ |
{ &vop_fsync_desc, fifo_fsync }, /* fsync */ |
{ &vop_fsync_desc, fifo_fsync }, /* fsync */ |
Line 187 fifo_open(void *v) |
|
Line 181 fifo_open(void *v) |
|
return (error); |
return (error); |
} |
} |
fip->fi_readers = fip->fi_writers = 0; |
fip->fi_readers = fip->fi_writers = 0; |
fip->fi_opencount = 0; |
|
wso->so_state |= SS_CANTRCVMORE; |
wso->so_state |= SS_CANTRCVMORE; |
rso->so_state |= SS_CANTSENDMORE; |
rso->so_state |= SS_CANTSENDMORE; |
} |
} |
fip->fi_opencount++; |
|
if (ap->a_mode & FREAD) { |
if (ap->a_mode & FREAD) { |
if (fip->fi_readers++ == 0) { |
if (fip->fi_readers++ == 0) { |
fip->fi_writesock->so_state &= ~SS_CANTSENDMORE; |
fip->fi_writesock->so_state &= ~SS_CANTSENDMORE; |
Line 257 fifo_read(void *v) |
|
Line 249 fifo_read(void *v) |
|
} */ *ap = v; |
} */ *ap = v; |
struct uio *uio; |
struct uio *uio; |
struct socket *rso; |
struct socket *rso; |
int error; |
int error, startresid; |
size_t startresid; |
|
|
|
uio = ap->a_uio; |
uio = ap->a_uio; |
rso = ap->a_vp->v_fifoinfo->fi_readsock; |
rso = ap->a_vp->v_fifoinfo->fi_readsock; |
Line 433 fifo_close(void *v) |
|
Line 424 fifo_close(void *v) |
|
} */ *ap = v; |
} */ *ap = v; |
struct vnode *vp; |
struct vnode *vp; |
struct fifoinfo *fip; |
struct fifoinfo *fip; |
|
int error1, error2; |
|
|
vp = ap->a_vp; |
vp = ap->a_vp; |
fip = vp->v_fifoinfo; |
fip = vp->v_fifoinfo; |
Line 444 fifo_close(void *v) |
|
Line 436 fifo_close(void *v) |
|
if (--fip->fi_writers == 0) |
if (--fip->fi_writers == 0) |
socantrcvmore(fip->fi_readsock); |
socantrcvmore(fip->fi_readsock); |
} |
} |
if (--fip->fi_opencount == 0) { |
if (vp->v_usecount > 1) |
(void) soclose(fip->fi_readsock); |
return (0); |
(void) soclose(fip->fi_writesock); |
error1 = soclose(fip->fi_readsock); |
FREE(fip, M_VNODE); |
error2 = soclose(fip->fi_writesock); |
vp->v_fifoinfo = NULL; |
FREE(fip, M_VNODE); |
} |
vp->v_fifoinfo = NULL; |
return (0); |
if (error1) |
|
return (error1); |
|
return (error2); |
} |
} |
|
|
/* |
/* |
Line 513 fifo_pathconf(void *v) |
|
Line 507 fifo_pathconf(void *v) |
|
/* NOTREACHED */ |
/* NOTREACHED */ |
} |
} |
|
|
static void |
/* |
filt_fifordetach(struct knote *kn) |
* Dummy putpages routine. |
{ |
*/ |
struct socket *so; |
|
|
|
so = (struct socket *)kn->kn_hook; |
|
SLIST_REMOVE(&so->so_rcv.sb_sel.si_klist, kn, knote, kn_selnext); |
|
if (SLIST_EMPTY(&so->so_rcv.sb_sel.si_klist)) |
|
so->so_rcv.sb_flags &= ~SB_KNOTE; |
|
} |
|
|
|
static int |
|
filt_fiforead(struct knote *kn, long hint) |
|
{ |
|
struct socket *so; |
|
|
|
so = (struct socket *)kn->kn_hook; |
|
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 void |
|
filt_fifowdetach(struct knote *kn) |
|
{ |
|
struct socket *so; |
|
|
|
so = (struct socket *)kn->kn_hook; |
|
SLIST_REMOVE(&so->so_snd.sb_sel.si_klist, kn, knote, kn_selnext); |
|
if (SLIST_EMPTY(&so->so_snd.sb_sel.si_klist)) |
|
so->so_snd.sb_flags &= ~SB_KNOTE; |
|
} |
|
|
|
static int |
|
filt_fifowrite(struct knote *kn, long hint) |
|
{ |
|
struct socket *so; |
|
|
|
so = (struct socket *)kn->kn_hook; |
|
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); |
|
} |
|
|
|
static const struct filterops fiforead_filtops = |
|
{ 1, NULL, filt_fifordetach, filt_fiforead }; |
|
static const struct filterops fifowrite_filtops = |
|
{ 1, NULL, filt_fifowdetach, filt_fifowrite }; |
|
|
|
/* ARGSUSED */ |
|
int |
int |
fifo_kqfilter(void *v) |
fifo_putpages(void *v) |
{ |
{ |
struct vop_kqfilter_args /* { |
struct vop_putpages_args /* { |
struct vnode *a_vp; |
struct vnode *a_vp; |
struct knote *a_kn; |
voff_t a_offlo; |
|
voff_t a_offhi; |
|
int a_flags; |
} */ *ap = v; |
} */ *ap = v; |
struct socket *so; |
struct vnode *vp = ap->a_vp; |
struct sockbuf *sb; |
struct uvm_object *uobj = &vp->v_uobj; |
|
|
so = (struct socket *)ap->a_vp->v_fifoinfo->fi_readsock; |
|
switch (ap->a_kn->kn_filter) { |
|
case EVFILT_READ: |
|
ap->a_kn->kn_fop = &fiforead_filtops; |
|
sb = &so->so_rcv; |
|
break; |
|
case EVFILT_WRITE: |
|
ap->a_kn->kn_fop = &fifowrite_filtops; |
|
sb = &so->so_snd; |
|
break; |
|
default: |
|
return (1); |
|
} |
|
|
|
ap->a_kn->kn_hook = so; |
|
|
|
SLIST_INSERT_HEAD(&sb->sb_sel.si_klist, ap->a_kn, kn_selnext); |
KASSERT(uobj->uo_npages == 0); |
sb->sb_flags |= SB_KNOTE; |
simple_unlock(&uobj->vmobjlock); |
return (0); |
return (0); |
} |
} |