Home | History | Annotate | Line # | Download | only in fifofs
fifo_vnops.c revision 1.1.1.2
      1      1.1   cgd /*
      2  1.1.1.2  fvdl  * Copyright (c) 1990, 1993
      3  1.1.1.2  fvdl  *	The Regents of the University of California.  All rights reserved.
      4      1.1   cgd  *
      5      1.1   cgd  * Redistribution and use in source and binary forms, with or without
      6      1.1   cgd  * modification, are permitted provided that the following conditions
      7      1.1   cgd  * are met:
      8      1.1   cgd  * 1. Redistributions of source code must retain the above copyright
      9      1.1   cgd  *    notice, this list of conditions and the following disclaimer.
     10      1.1   cgd  * 2. Redistributions in binary form must reproduce the above copyright
     11      1.1   cgd  *    notice, this list of conditions and the following disclaimer in the
     12      1.1   cgd  *    documentation and/or other materials provided with the distribution.
     13      1.1   cgd  * 3. All advertising materials mentioning features or use of this software
     14      1.1   cgd  *    must display the following acknowledgement:
     15      1.1   cgd  *	This product includes software developed by the University of
     16      1.1   cgd  *	California, Berkeley and its contributors.
     17      1.1   cgd  * 4. Neither the name of the University nor the names of its contributors
     18      1.1   cgd  *    may be used to endorse or promote products derived from this software
     19      1.1   cgd  *    without specific prior written permission.
     20      1.1   cgd  *
     21      1.1   cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     22      1.1   cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     23      1.1   cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     24      1.1   cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     25      1.1   cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     26      1.1   cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     27      1.1   cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     28      1.1   cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     29      1.1   cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     30      1.1   cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     31      1.1   cgd  * SUCH DAMAGE.
     32      1.1   cgd  *
     33  1.1.1.2  fvdl  *	@(#)fifo_vnops.c	8.2 (Berkeley) 1/4/94
     34      1.1   cgd  */
     35      1.1   cgd 
     36  1.1.1.2  fvdl #include <sys/param.h>
     37  1.1.1.2  fvdl #include <sys/proc.h>
     38  1.1.1.2  fvdl #include <sys/time.h>
     39  1.1.1.2  fvdl #include <sys/namei.h>
     40  1.1.1.2  fvdl #include <sys/vnode.h>
     41  1.1.1.2  fvdl #include <sys/socket.h>
     42  1.1.1.2  fvdl #include <sys/socketvar.h>
     43  1.1.1.2  fvdl #include <sys/stat.h>
     44  1.1.1.2  fvdl #include <sys/systm.h>
     45  1.1.1.2  fvdl #include <sys/ioctl.h>
     46  1.1.1.2  fvdl #include <sys/file.h>
     47  1.1.1.2  fvdl #include <sys/errno.h>
     48  1.1.1.2  fvdl #include <sys/malloc.h>
     49  1.1.1.2  fvdl #include <miscfs/fifofs/fifo.h>
     50      1.1   cgd 
     51      1.1   cgd /*
     52      1.1   cgd  * This structure is associated with the FIFO vnode and stores
     53      1.1   cgd  * the state associated with the FIFO.
     54      1.1   cgd  */
     55      1.1   cgd struct fifoinfo {
     56      1.1   cgd 	struct socket	*fi_readsock;
     57      1.1   cgd 	struct socket	*fi_writesock;
     58      1.1   cgd 	long		fi_readers;
     59      1.1   cgd 	long		fi_writers;
     60      1.1   cgd };
     61      1.1   cgd 
     62  1.1.1.2  fvdl int (**fifo_vnodeop_p)();
     63  1.1.1.2  fvdl struct vnodeopv_entry_desc fifo_vnodeop_entries[] = {
     64  1.1.1.2  fvdl 	{ &vop_default_desc, vn_default_error },
     65  1.1.1.2  fvdl 	{ &vop_lookup_desc, fifo_lookup },		/* lookup */
     66  1.1.1.2  fvdl 	{ &vop_create_desc, fifo_create },		/* create */
     67  1.1.1.2  fvdl 	{ &vop_mknod_desc, fifo_mknod },		/* mknod */
     68  1.1.1.2  fvdl 	{ &vop_open_desc, fifo_open },			/* open */
     69  1.1.1.2  fvdl 	{ &vop_close_desc, fifo_close },		/* close */
     70  1.1.1.2  fvdl 	{ &vop_access_desc, fifo_access },		/* access */
     71  1.1.1.2  fvdl 	{ &vop_getattr_desc, fifo_getattr },		/* getattr */
     72  1.1.1.2  fvdl 	{ &vop_setattr_desc, fifo_setattr },		/* setattr */
     73  1.1.1.2  fvdl 	{ &vop_read_desc, fifo_read },			/* read */
     74  1.1.1.2  fvdl 	{ &vop_write_desc, fifo_write },		/* write */
     75  1.1.1.2  fvdl 	{ &vop_ioctl_desc, fifo_ioctl },		/* ioctl */
     76  1.1.1.2  fvdl 	{ &vop_select_desc, fifo_select },		/* select */
     77  1.1.1.2  fvdl 	{ &vop_mmap_desc, fifo_mmap },			/* mmap */
     78  1.1.1.2  fvdl 	{ &vop_fsync_desc, fifo_fsync },		/* fsync */
     79  1.1.1.2  fvdl 	{ &vop_seek_desc, fifo_seek },			/* seek */
     80  1.1.1.2  fvdl 	{ &vop_remove_desc, fifo_remove },		/* remove */
     81  1.1.1.2  fvdl 	{ &vop_link_desc, fifo_link },			/* link */
     82  1.1.1.2  fvdl 	{ &vop_rename_desc, fifo_rename },		/* rename */
     83  1.1.1.2  fvdl 	{ &vop_mkdir_desc, fifo_mkdir },		/* mkdir */
     84  1.1.1.2  fvdl 	{ &vop_rmdir_desc, fifo_rmdir },		/* rmdir */
     85  1.1.1.2  fvdl 	{ &vop_symlink_desc, fifo_symlink },		/* symlink */
     86  1.1.1.2  fvdl 	{ &vop_readdir_desc, fifo_readdir },		/* readdir */
     87  1.1.1.2  fvdl 	{ &vop_readlink_desc, fifo_readlink },		/* readlink */
     88  1.1.1.2  fvdl 	{ &vop_abortop_desc, fifo_abortop },		/* abortop */
     89  1.1.1.2  fvdl 	{ &vop_inactive_desc, fifo_inactive },		/* inactive */
     90  1.1.1.2  fvdl 	{ &vop_reclaim_desc, fifo_reclaim },		/* reclaim */
     91  1.1.1.2  fvdl 	{ &vop_lock_desc, fifo_lock },			/* lock */
     92  1.1.1.2  fvdl 	{ &vop_unlock_desc, fifo_unlock },		/* unlock */
     93  1.1.1.2  fvdl 	{ &vop_bmap_desc, fifo_bmap },			/* bmap */
     94  1.1.1.2  fvdl 	{ &vop_strategy_desc, fifo_strategy },		/* strategy */
     95  1.1.1.2  fvdl 	{ &vop_print_desc, fifo_print },		/* print */
     96  1.1.1.2  fvdl 	{ &vop_islocked_desc, fifo_islocked },		/* islocked */
     97  1.1.1.2  fvdl 	{ &vop_pathconf_desc, fifo_pathconf },		/* pathconf */
     98  1.1.1.2  fvdl 	{ &vop_advlock_desc, fifo_advlock },		/* advlock */
     99  1.1.1.2  fvdl 	{ &vop_blkatoff_desc, fifo_blkatoff },		/* blkatoff */
    100  1.1.1.2  fvdl 	{ &vop_valloc_desc, fifo_valloc },		/* valloc */
    101  1.1.1.2  fvdl 	{ &vop_vfree_desc, fifo_vfree },		/* vfree */
    102  1.1.1.2  fvdl 	{ &vop_truncate_desc, fifo_truncate },		/* truncate */
    103  1.1.1.2  fvdl 	{ &vop_update_desc, fifo_update },		/* update */
    104  1.1.1.2  fvdl 	{ &vop_bwrite_desc, fifo_bwrite },		/* bwrite */
    105  1.1.1.2  fvdl 	{ (struct vnodeop_desc*)NULL, (int(*)())NULL }
    106      1.1   cgd };
    107  1.1.1.2  fvdl struct vnodeopv_desc fifo_vnodeop_opv_desc =
    108  1.1.1.2  fvdl 	{ &fifo_vnodeop_p, fifo_vnodeop_entries };
    109      1.1   cgd 
    110      1.1   cgd /*
    111      1.1   cgd  * Trivial lookup routine that always fails.
    112      1.1   cgd  */
    113      1.1   cgd /* ARGSUSED */
    114  1.1.1.2  fvdl fifo_lookup(ap)
    115  1.1.1.2  fvdl 	struct vop_lookup_args /* {
    116  1.1.1.2  fvdl 		struct vnode * a_dvp;
    117  1.1.1.2  fvdl 		struct vnode ** a_vpp;
    118  1.1.1.2  fvdl 		struct componentname * a_cnp;
    119  1.1.1.2  fvdl 	} */ *ap;
    120      1.1   cgd {
    121  1.1.1.2  fvdl 
    122  1.1.1.2  fvdl 	*ap->a_vpp = NULL;
    123      1.1   cgd 	return (ENOTDIR);
    124      1.1   cgd }
    125      1.1   cgd 
    126      1.1   cgd /*
    127      1.1   cgd  * Open called to set up a new instance of a fifo or
    128      1.1   cgd  * to find an active instance of a fifo.
    129      1.1   cgd  */
    130      1.1   cgd /* ARGSUSED */
    131  1.1.1.2  fvdl fifo_open(ap)
    132  1.1.1.2  fvdl 	struct vop_open_args /* {
    133  1.1.1.2  fvdl 		struct vnode *a_vp;
    134  1.1.1.2  fvdl 		int  a_mode;
    135  1.1.1.2  fvdl 		struct ucred *a_cred;
    136  1.1.1.2  fvdl 		struct proc *a_p;
    137  1.1.1.2  fvdl 	} */ *ap;
    138      1.1   cgd {
    139  1.1.1.2  fvdl 	register struct vnode *vp = ap->a_vp;
    140      1.1   cgd 	register struct fifoinfo *fip;
    141      1.1   cgd 	struct socket *rso, *wso;
    142      1.1   cgd 	int error;
    143      1.1   cgd 	static char openstr[] = "fifo";
    144      1.1   cgd 
    145  1.1.1.2  fvdl 	if ((ap->a_mode & (FREAD|FWRITE)) == (FREAD|FWRITE))
    146      1.1   cgd 		return (EINVAL);
    147      1.1   cgd 	if ((fip = vp->v_fifoinfo) == NULL) {
    148      1.1   cgd 		MALLOC(fip, struct fifoinfo *, sizeof(*fip), M_VNODE, M_WAITOK);
    149      1.1   cgd 		vp->v_fifoinfo = fip;
    150      1.1   cgd 		if (error = socreate(AF_UNIX, &rso, SOCK_STREAM, 0)) {
    151      1.1   cgd 			free(fip, M_VNODE);
    152      1.1   cgd 			vp->v_fifoinfo = NULL;
    153      1.1   cgd 			return (error);
    154      1.1   cgd 		}
    155      1.1   cgd 		fip->fi_readsock = rso;
    156      1.1   cgd 		if (error = socreate(AF_UNIX, &wso, SOCK_STREAM, 0)) {
    157      1.1   cgd 			(void)soclose(rso);
    158      1.1   cgd 			free(fip, M_VNODE);
    159      1.1   cgd 			vp->v_fifoinfo = NULL;
    160      1.1   cgd 			return (error);
    161      1.1   cgd 		}
    162      1.1   cgd 		fip->fi_writesock = wso;
    163      1.1   cgd 		if (error = unp_connect2(wso, rso)) {
    164      1.1   cgd 			(void)soclose(wso);
    165      1.1   cgd 			(void)soclose(rso);
    166      1.1   cgd 			free(fip, M_VNODE);
    167      1.1   cgd 			vp->v_fifoinfo = NULL;
    168      1.1   cgd 			return (error);
    169      1.1   cgd 		}
    170  1.1.1.2  fvdl 		fip->fi_readers = fip->fi_writers = 0;
    171      1.1   cgd 		wso->so_state |= SS_CANTRCVMORE;
    172      1.1   cgd 		rso->so_state |= SS_CANTSENDMORE;
    173      1.1   cgd 	}
    174      1.1   cgd 	error = 0;
    175  1.1.1.2  fvdl 	if (ap->a_mode & FREAD) {
    176      1.1   cgd 		fip->fi_readers++;
    177      1.1   cgd 		if (fip->fi_readers == 1) {
    178      1.1   cgd 			fip->fi_writesock->so_state &= ~SS_CANTSENDMORE;
    179      1.1   cgd 			if (fip->fi_writers > 0)
    180      1.1   cgd 				wakeup((caddr_t)&fip->fi_writers);
    181      1.1   cgd 		}
    182  1.1.1.2  fvdl 		if (ap->a_mode & O_NONBLOCK)
    183      1.1   cgd 			return (0);
    184  1.1.1.2  fvdl 		while (fip->fi_writers == 0) {
    185  1.1.1.2  fvdl 			VOP_UNLOCK(vp);
    186  1.1.1.2  fvdl 			error = tsleep((caddr_t)&fip->fi_readers,
    187  1.1.1.2  fvdl 			    PCATCH | PSOCK, openstr, 0);
    188  1.1.1.2  fvdl 			VOP_LOCK(vp);
    189  1.1.1.2  fvdl 			if (error)
    190      1.1   cgd 				break;
    191  1.1.1.2  fvdl 		}
    192      1.1   cgd 	} else {
    193      1.1   cgd 		fip->fi_writers++;
    194  1.1.1.2  fvdl 		if (fip->fi_readers == 0 && (ap->a_mode & O_NONBLOCK)) {
    195      1.1   cgd 			error = ENXIO;
    196      1.1   cgd 		} else {
    197      1.1   cgd 			if (fip->fi_writers == 1) {
    198      1.1   cgd 				fip->fi_readsock->so_state &= ~SS_CANTRCVMORE;
    199      1.1   cgd 				if (fip->fi_readers > 0)
    200      1.1   cgd 					wakeup((caddr_t)&fip->fi_readers);
    201      1.1   cgd 			}
    202  1.1.1.2  fvdl 			while (fip->fi_readers == 0) {
    203  1.1.1.2  fvdl 				VOP_UNLOCK(vp);
    204  1.1.1.2  fvdl 				error = tsleep((caddr_t)&fip->fi_writers,
    205  1.1.1.2  fvdl 				    PCATCH | PSOCK, openstr, 0);
    206  1.1.1.2  fvdl 				VOP_LOCK(vp);
    207  1.1.1.2  fvdl 				if (error)
    208      1.1   cgd 					break;
    209  1.1.1.2  fvdl 			}
    210      1.1   cgd 		}
    211      1.1   cgd 	}
    212      1.1   cgd 	if (error)
    213  1.1.1.2  fvdl 		VOP_CLOSE(vp, ap->a_mode, ap->a_cred, ap->a_p);
    214      1.1   cgd 	return (error);
    215      1.1   cgd }
    216      1.1   cgd 
    217      1.1   cgd /*
    218      1.1   cgd  * Vnode op for read
    219      1.1   cgd  */
    220      1.1   cgd /* ARGSUSED */
    221  1.1.1.2  fvdl fifo_read(ap)
    222  1.1.1.2  fvdl 	struct vop_read_args /* {
    223  1.1.1.2  fvdl 		struct vnode *a_vp;
    224  1.1.1.2  fvdl 		struct uio *a_uio;
    225  1.1.1.2  fvdl 		int  a_ioflag;
    226  1.1.1.2  fvdl 		struct ucred *a_cred;
    227  1.1.1.2  fvdl 	} */ *ap;
    228      1.1   cgd {
    229  1.1.1.2  fvdl 	register struct uio *uio = ap->a_uio;
    230  1.1.1.2  fvdl 	register struct socket *rso = ap->a_vp->v_fifoinfo->fi_readsock;
    231      1.1   cgd 	int error, startresid;
    232      1.1   cgd 
    233      1.1   cgd #ifdef DIAGNOSTIC
    234      1.1   cgd 	if (uio->uio_rw != UIO_READ)
    235      1.1   cgd 		panic("fifo_read mode");
    236      1.1   cgd #endif
    237      1.1   cgd 	if (uio->uio_resid == 0)
    238      1.1   cgd 		return (0);
    239  1.1.1.2  fvdl 	if (ap->a_ioflag & IO_NDELAY)
    240      1.1   cgd 		rso->so_state |= SS_NBIO;
    241      1.1   cgd 	startresid = uio->uio_resid;
    242  1.1.1.2  fvdl 	VOP_UNLOCK(ap->a_vp);
    243      1.1   cgd 	error = soreceive(rso, (struct mbuf **)0, uio, (int *)0,
    244      1.1   cgd 		(struct mbuf **)0, (struct mbuf **)0);
    245  1.1.1.2  fvdl 	VOP_LOCK(ap->a_vp);
    246      1.1   cgd 	/*
    247      1.1   cgd 	 * Clear EOF indication after first such return.
    248      1.1   cgd 	 */
    249      1.1   cgd 	if (uio->uio_resid == startresid)
    250      1.1   cgd 		rso->so_state &= ~SS_CANTRCVMORE;
    251  1.1.1.2  fvdl 	if (ap->a_ioflag & IO_NDELAY)
    252      1.1   cgd 		rso->so_state &= ~SS_NBIO;
    253      1.1   cgd 	return (error);
    254      1.1   cgd }
    255      1.1   cgd 
    256      1.1   cgd /*
    257      1.1   cgd  * Vnode op for write
    258      1.1   cgd  */
    259      1.1   cgd /* ARGSUSED */
    260  1.1.1.2  fvdl fifo_write(ap)
    261  1.1.1.2  fvdl 	struct vop_write_args /* {
    262  1.1.1.2  fvdl 		struct vnode *a_vp;
    263  1.1.1.2  fvdl 		struct uio *a_uio;
    264  1.1.1.2  fvdl 		int  a_ioflag;
    265  1.1.1.2  fvdl 		struct ucred *a_cred;
    266  1.1.1.2  fvdl 	} */ *ap;
    267      1.1   cgd {
    268  1.1.1.2  fvdl 	struct socket *wso = ap->a_vp->v_fifoinfo->fi_writesock;
    269      1.1   cgd 	int error;
    270      1.1   cgd 
    271      1.1   cgd #ifdef DIAGNOSTIC
    272  1.1.1.2  fvdl 	if (ap->a_uio->uio_rw != UIO_WRITE)
    273      1.1   cgd 		panic("fifo_write mode");
    274      1.1   cgd #endif
    275  1.1.1.2  fvdl 	if (ap->a_ioflag & IO_NDELAY)
    276      1.1   cgd 		wso->so_state |= SS_NBIO;
    277  1.1.1.2  fvdl 	VOP_UNLOCK(ap->a_vp);
    278  1.1.1.2  fvdl 	error = sosend(wso, (struct mbuf *)0, ap->a_uio, 0, (struct mbuf *)0, 0);
    279  1.1.1.2  fvdl 	VOP_LOCK(ap->a_vp);
    280  1.1.1.2  fvdl 	if (ap->a_ioflag & IO_NDELAY)
    281      1.1   cgd 		wso->so_state &= ~SS_NBIO;
    282      1.1   cgd 	return (error);
    283      1.1   cgd }
    284      1.1   cgd 
    285      1.1   cgd /*
    286      1.1   cgd  * Device ioctl operation.
    287      1.1   cgd  */
    288      1.1   cgd /* ARGSUSED */
    289  1.1.1.2  fvdl fifo_ioctl(ap)
    290  1.1.1.2  fvdl 	struct vop_ioctl_args /* {
    291  1.1.1.2  fvdl 		struct vnode *a_vp;
    292  1.1.1.2  fvdl 		int  a_command;
    293  1.1.1.2  fvdl 		caddr_t  a_data;
    294  1.1.1.2  fvdl 		int  a_fflag;
    295  1.1.1.2  fvdl 		struct ucred *a_cred;
    296  1.1.1.2  fvdl 		struct proc *a_p;
    297  1.1.1.2  fvdl 	} */ *ap;
    298      1.1   cgd {
    299      1.1   cgd 	struct file filetmp;
    300      1.1   cgd 
    301  1.1.1.2  fvdl 	if (ap->a_command == FIONBIO)
    302      1.1   cgd 		return (0);
    303  1.1.1.2  fvdl 	if (ap->a_fflag & FREAD)
    304  1.1.1.2  fvdl 		filetmp.f_data = (caddr_t)ap->a_vp->v_fifoinfo->fi_readsock;
    305      1.1   cgd 	else
    306  1.1.1.2  fvdl 		filetmp.f_data = (caddr_t)ap->a_vp->v_fifoinfo->fi_writesock;
    307  1.1.1.2  fvdl 	return (soo_ioctl(&filetmp, ap->a_command, ap->a_data, ap->a_p));
    308      1.1   cgd }
    309      1.1   cgd 
    310      1.1   cgd /* ARGSUSED */
    311  1.1.1.2  fvdl fifo_select(ap)
    312  1.1.1.2  fvdl 	struct vop_select_args /* {
    313  1.1.1.2  fvdl 		struct vnode *a_vp;
    314  1.1.1.2  fvdl 		int  a_which;
    315  1.1.1.2  fvdl 		int  a_fflags;
    316  1.1.1.2  fvdl 		struct ucred *a_cred;
    317  1.1.1.2  fvdl 		struct proc *a_p;
    318  1.1.1.2  fvdl 	} */ *ap;
    319      1.1   cgd {
    320      1.1   cgd 	struct file filetmp;
    321      1.1   cgd 
    322  1.1.1.2  fvdl 	if (ap->a_fflags & FREAD)
    323  1.1.1.2  fvdl 		filetmp.f_data = (caddr_t)ap->a_vp->v_fifoinfo->fi_readsock;
    324      1.1   cgd 	else
    325  1.1.1.2  fvdl 		filetmp.f_data = (caddr_t)ap->a_vp->v_fifoinfo->fi_writesock;
    326  1.1.1.2  fvdl 	return (soo_select(&filetmp, ap->a_which, ap->a_p));
    327      1.1   cgd }
    328      1.1   cgd 
    329      1.1   cgd /*
    330      1.1   cgd  * This is a noop, simply returning what one has been given.
    331      1.1   cgd  */
    332  1.1.1.2  fvdl fifo_bmap(ap)
    333  1.1.1.2  fvdl 	struct vop_bmap_args /* {
    334  1.1.1.2  fvdl 		struct vnode *a_vp;
    335  1.1.1.2  fvdl 		daddr_t  a_bn;
    336  1.1.1.2  fvdl 		struct vnode **a_vpp;
    337  1.1.1.2  fvdl 		daddr_t *a_bnp;
    338  1.1.1.2  fvdl 	} */ *ap;
    339      1.1   cgd {
    340      1.1   cgd 
    341  1.1.1.2  fvdl 	if (ap->a_vpp != NULL)
    342  1.1.1.2  fvdl 		*ap->a_vpp = ap->a_vp;
    343  1.1.1.2  fvdl 	if (ap->a_bnp != NULL)
    344  1.1.1.2  fvdl 		*ap->a_bnp = ap->a_bn;
    345      1.1   cgd 	return (0);
    346      1.1   cgd }
    347      1.1   cgd 
    348      1.1   cgd /*
    349      1.1   cgd  * At the moment we do not do any locking.
    350      1.1   cgd  */
    351      1.1   cgd /* ARGSUSED */
    352  1.1.1.2  fvdl fifo_lock(ap)
    353  1.1.1.2  fvdl 	struct vop_lock_args /* {
    354  1.1.1.2  fvdl 		struct vnode *a_vp;
    355  1.1.1.2  fvdl 	} */ *ap;
    356      1.1   cgd {
    357      1.1   cgd 
    358      1.1   cgd 	return (0);
    359      1.1   cgd }
    360      1.1   cgd 
    361      1.1   cgd /* ARGSUSED */
    362  1.1.1.2  fvdl fifo_unlock(ap)
    363  1.1.1.2  fvdl 	struct vop_unlock_args /* {
    364  1.1.1.2  fvdl 		struct vnode *a_vp;
    365  1.1.1.2  fvdl 	} */ *ap;
    366      1.1   cgd {
    367      1.1   cgd 
    368      1.1   cgd 	return (0);
    369      1.1   cgd }
    370      1.1   cgd 
    371      1.1   cgd /*
    372      1.1   cgd  * Device close routine
    373      1.1   cgd  */
    374      1.1   cgd /* ARGSUSED */
    375  1.1.1.2  fvdl fifo_close(ap)
    376  1.1.1.2  fvdl 	struct vop_close_args /* {
    377  1.1.1.2  fvdl 		struct vnode *a_vp;
    378  1.1.1.2  fvdl 		int  a_fflag;
    379  1.1.1.2  fvdl 		struct ucred *a_cred;
    380  1.1.1.2  fvdl 		struct proc *a_p;
    381  1.1.1.2  fvdl 	} */ *ap;
    382      1.1   cgd {
    383  1.1.1.2  fvdl 	register struct vnode *vp = ap->a_vp;
    384      1.1   cgd 	register struct fifoinfo *fip = vp->v_fifoinfo;
    385      1.1   cgd 	int error1, error2;
    386      1.1   cgd 
    387  1.1.1.2  fvdl 	if (ap->a_fflag & FWRITE) {
    388      1.1   cgd 		fip->fi_writers--;
    389      1.1   cgd 		if (fip->fi_writers == 0)
    390      1.1   cgd 			socantrcvmore(fip->fi_readsock);
    391      1.1   cgd 	} else {
    392      1.1   cgd 		fip->fi_readers--;
    393      1.1   cgd 		if (fip->fi_readers == 0)
    394      1.1   cgd 			socantsendmore(fip->fi_writesock);
    395      1.1   cgd 	}
    396      1.1   cgd 	if (vp->v_usecount > 1)
    397      1.1   cgd 		return (0);
    398      1.1   cgd 	error1 = soclose(fip->fi_readsock);
    399      1.1   cgd 	error2 = soclose(fip->fi_writesock);
    400      1.1   cgd 	FREE(fip, M_VNODE);
    401      1.1   cgd 	vp->v_fifoinfo = NULL;
    402      1.1   cgd 	if (error1)
    403      1.1   cgd 		return (error1);
    404      1.1   cgd 	return (error2);
    405      1.1   cgd }
    406      1.1   cgd 
    407      1.1   cgd /*
    408      1.1   cgd  * Print out the contents of a fifo vnode.
    409      1.1   cgd  */
    410  1.1.1.2  fvdl fifo_print(ap)
    411  1.1.1.2  fvdl 	struct vop_print_args /* {
    412  1.1.1.2  fvdl 		struct vnode *a_vp;
    413  1.1.1.2  fvdl 	} */ *ap;
    414      1.1   cgd {
    415      1.1   cgd 
    416      1.1   cgd 	printf("tag VT_NON");
    417  1.1.1.2  fvdl 	fifo_printinfo(ap->a_vp);
    418      1.1   cgd 	printf("\n");
    419      1.1   cgd }
    420      1.1   cgd 
    421      1.1   cgd /*
    422      1.1   cgd  * Print out internal contents of a fifo vnode.
    423      1.1   cgd  */
    424      1.1   cgd fifo_printinfo(vp)
    425      1.1   cgd 	struct vnode *vp;
    426      1.1   cgd {
    427      1.1   cgd 	register struct fifoinfo *fip = vp->v_fifoinfo;
    428      1.1   cgd 
    429      1.1   cgd 	printf(", fifo with %d readers and %d writers",
    430      1.1   cgd 		fip->fi_readers, fip->fi_writers);
    431      1.1   cgd }
    432      1.1   cgd 
    433      1.1   cgd /*
    434  1.1.1.2  fvdl  * Return POSIX pathconf information applicable to fifo's.
    435  1.1.1.2  fvdl  */
    436  1.1.1.2  fvdl fifo_pathconf(ap)
    437  1.1.1.2  fvdl 	struct vop_pathconf_args /* {
    438  1.1.1.2  fvdl 		struct vnode *a_vp;
    439  1.1.1.2  fvdl 		int a_name;
    440  1.1.1.2  fvdl 		int *a_retval;
    441  1.1.1.2  fvdl 	} */ *ap;
    442  1.1.1.2  fvdl {
    443  1.1.1.2  fvdl 
    444  1.1.1.2  fvdl 	switch (ap->a_name) {
    445  1.1.1.2  fvdl 	case _PC_LINK_MAX:
    446  1.1.1.2  fvdl 		*ap->a_retval = LINK_MAX;
    447  1.1.1.2  fvdl 		return (0);
    448  1.1.1.2  fvdl 	case _PC_PIPE_BUF:
    449  1.1.1.2  fvdl 		*ap->a_retval = PIPE_BUF;
    450  1.1.1.2  fvdl 		return (0);
    451  1.1.1.2  fvdl 	case _PC_CHOWN_RESTRICTED:
    452  1.1.1.2  fvdl 		*ap->a_retval = 1;
    453  1.1.1.2  fvdl 		return (0);
    454  1.1.1.2  fvdl 	default:
    455  1.1.1.2  fvdl 		return (EINVAL);
    456  1.1.1.2  fvdl 	}
    457  1.1.1.2  fvdl 	/* NOTREACHED */
    458  1.1.1.2  fvdl }
    459  1.1.1.2  fvdl 
    460  1.1.1.2  fvdl /*
    461      1.1   cgd  * Fifo failed operation
    462      1.1   cgd  */
    463      1.1   cgd fifo_ebadf()
    464      1.1   cgd {
    465      1.1   cgd 
    466      1.1   cgd 	return (EBADF);
    467      1.1   cgd }
    468      1.1   cgd 
    469      1.1   cgd /*
    470      1.1   cgd  * Fifo advisory byte-level locks.
    471      1.1   cgd  */
    472      1.1   cgd /* ARGSUSED */
    473  1.1.1.2  fvdl fifo_advlock(ap)
    474  1.1.1.2  fvdl 	struct vop_advlock_args /* {
    475  1.1.1.2  fvdl 		struct vnode *a_vp;
    476  1.1.1.2  fvdl 		caddr_t  a_id;
    477  1.1.1.2  fvdl 		int  a_op;
    478  1.1.1.2  fvdl 		struct flock *a_fl;
    479  1.1.1.2  fvdl 		int  a_flags;
    480  1.1.1.2  fvdl 	} */ *ap;
    481      1.1   cgd {
    482      1.1   cgd 
    483      1.1   cgd 	return (EOPNOTSUPP);
    484      1.1   cgd }
    485      1.1   cgd 
    486      1.1   cgd /*
    487      1.1   cgd  * Fifo bad operation
    488      1.1   cgd  */
    489      1.1   cgd fifo_badop()
    490      1.1   cgd {
    491      1.1   cgd 
    492      1.1   cgd 	panic("fifo_badop called");
    493      1.1   cgd 	/* NOTREACHED */
    494      1.1   cgd }
    495