/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 1990, 1993, 1995
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)fifo_vnops.c 8.10 (Berkeley) 5/27/95
*/
/*
* This structure is associated with the FIFO vnode and stores
* the state associated with the FIFO.
*/
struct fifoinfo {
struct socket *fi_readsock;
struct socket *fi_writesock;
kcondvar_t fi_rcv;
int fi_readers;
kcondvar_t fi_wcv;
int fi_writers;
};
/*
* Open called to set up a new instance of a fifo or
* to find an active instance of a fifo.
*/
static int
fifo_open(void *v)
{
struct vop_open_args /* {
struct vnode *a_vp;
int a_mode;
kauth_cred_t a_cred;
} */ *ap = v;
struct lwp *l = curlwp;
struct vnode *vp;
struct fifoinfo *fip;
struct socket *rso, *wso;
int error;
/*
* FIFOs must be readable when there is at least 1
* byte of data available in the receive buffer.
*
* FIFOs must be writable when there is space for
* at least PIPE_BUF bytes in the send buffer.
* If we're increasing the low water mark for the
* send buffer, then mimic how soreserve() would
* have set the high water mark.
*/
rso->so_rcv.sb_lowat = 1;
if (wso->so_snd.sb_lowat < PIPE_BUF) {
wso->so_snd.sb_hiwat = PIPE_BUF * 2;
}
wso->so_snd.sb_lowat = PIPE_BUF;
if (rso != NULL) {
events = ap->a_events & (POLLIN | POLLRDNORM);
if (events != 0 && soreadable(rso)) {
revents |= events;
}
if (rso->so_state & SS_CANTRCVMORE) {
revents |= POLLHUP;
}
/*
* We always selrecord the read side here regardless
* of the caller's read interest because we need to
* action POLLHUP.
*/
if (revents == 0) {
selrecord(curlwp, &rso->so_rcv.sb_sel);
rso->so_rcv.sb_flags |= SB_NOTIFY;
}
}
/*
* This is a noop, simply returning what one has been given.
*/
static int
fifo_bmap(void *v)
{
struct vop_bmap_args /* {
struct vnode *a_vp;
daddr_t a_bn;
struct vnode **a_vpp;
daddr_t *a_bnp;
int *a_runp;
} */ *ap = v;
if (ap->a_vpp != NULL)
*ap->a_vpp = ap->a_vp;
if (ap->a_bnp != NULL)
*ap->a_bnp = ap->a_bn;
if (ap->a_runp != NULL)
*ap->a_runp = 0;
return (0);
}
/*
* This is like socantrcvmore(), but we send the POLL_HUP code.
*/
static void
fifo_socantrcvmore(struct socket *so)
{
KASSERT(solocked(so));
/*
* Print out internal contents of a fifo vnode.
*/
static void
fifo_printinfo(struct vnode *vp)
{
struct fifoinfo *fip;
fip = vp->v_fifoinfo;
printf(", fifo with %d readers and %d writers",
fip->fi_readers, fip->fi_writers);
}
/*
* Print out the contents of a fifo vnode.
*/
static int
fifo_print(void *v)
{
struct vop_print_args /* {
struct vnode *a_vp;
} */ *ap = v;
/*
* We are most likely being called with the vnode belonging
* to some file system and this is not printed.
*/
if (ap->a_vp->v_tag == VT_NON)
printf("tag VT_NON");