]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/miscfs/fifofs/fifo_vnops.c
xnu-6153.11.26.tar.gz
[apple/xnu.git] / bsd / miscfs / fifofs / fifo_vnops.c
index 8d331189818cfebe3a70409943a169815f43fea9..df13d0d96537ebdd0404e846bd5e990c6856df0e 100644 (file)
@@ -1,31 +1,29 @@
 /*
- * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2019 Apple Inc. All rights reserved.
  *
- * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code 
- * as defined in and that are subject to the Apple Public Source License 
- * Version 2.0 (the 'License'). You may not use this file except in 
- * compliance with the License.  The rights granted to you under the 
- * License may not be used to create, or enable the creation or 
- * redistribution of, unlawful or unlicensed copies of an Apple operating 
- * system, or to circumvent, violate, or enable the circumvention or 
- * violation of, any terms of an Apple operating system software license 
- * agreement.
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
- * Please obtain a copy of the License at 
- * http://www.opensource.apple.com/apsl/ and read it before using this 
- * file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
  *
- * The Original Code and all software distributed under the License are 
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
- * Please see the License for the specific language governing rights and 
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
  * limitations under the License.
  *
- * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
 /*
 
 #define VOPFUNC int (*)(void *)
 
-extern int     soo_ioctl(struct fileproc *fp, u_long cmd, caddr_t data, struct proc *p);
-extern int     soo_select(struct fileproc *fp, int which, void * wql, struct proc *p);
-
-int (**fifo_vnodeop_p)(void *);
-struct vnodeopv_entry_desc fifo_vnodeop_entries[] = {
-       { &vnop_default_desc, (VOPFUNC)vn_default_error },
-       { &vnop_lookup_desc, (VOPFUNC)fifo_lookup },            /* lookup */
-       { &vnop_create_desc, (VOPFUNC)err_create },             /* create */
-       { &vnop_mknod_desc, (VOPFUNC)err_mknod },               /* mknod */
-       { &vnop_open_desc, (VOPFUNC)fifo_open },                        /* open */
-       { &vnop_close_desc, (VOPFUNC)fifo_close },              /* close */
-       { &vnop_access_desc, (VOPFUNC)fifo_access },            /* access */
-       { &vnop_getattr_desc, (VOPFUNC)fifo_getattr },          /* getattr */
-       { &vnop_setattr_desc, (VOPFUNC)fifo_setattr },          /* setattr */
-       { &vnop_read_desc, (VOPFUNC)fifo_read },                        /* read */
-       { &vnop_write_desc, (VOPFUNC)fifo_write },              /* write */
-       { &vnop_ioctl_desc, (VOPFUNC)fifo_ioctl },              /* ioctl */
-       { &vnop_select_desc, (VOPFUNC)fifo_select },            /* select */
-       { &vnop_revoke_desc, (VOPFUNC)fifo_revoke },            /* revoke */
-       { &vnop_mmap_desc, (VOPFUNC)err_mmap },                 /* mmap */
-       { &vnop_fsync_desc, (VOPFUNC)fifo_fsync },              /* fsync */
-       { &vnop_remove_desc, (VOPFUNC)err_remove },             /* remove */
-       { &vnop_link_desc, (VOPFUNC)err_link },                 /* link */
-       { &vnop_rename_desc, (VOPFUNC)err_rename },             /* rename */
-       { &vnop_mkdir_desc, (VOPFUNC)err_mkdir },               /* mkdir */
-       { &vnop_rmdir_desc, (VOPFUNC)err_rmdir },               /* rmdir */
-       { &vnop_symlink_desc, (VOPFUNC)err_symlink },           /* symlink */
-       { &vnop_readdir_desc, (VOPFUNC)err_readdir },           /* readdir */
-       { &vnop_readlink_desc, (VOPFUNC)err_readlink },         /* readlink */
-       { &vnop_inactive_desc, (VOPFUNC)fifo_inactive },                /* inactive */
-       { &vnop_reclaim_desc, (VOPFUNC)fifo_reclaim },          /* reclaim */
-       { &vnop_strategy_desc, (VOPFUNC)err_strategy },         /* strategy */
-       { &vnop_pathconf_desc, (VOPFUNC)fifo_pathconf },                /* pathconf */
-       { &vnop_advlock_desc, (VOPFUNC)fifo_advlock },          /* advlock */
-       { &vnop_bwrite_desc, (VOPFUNC)fifo_bwrite },            /* bwrite */
-       { &vnop_pagein_desc, (VOPFUNC)err_pagein },             /* Pagein */
-       { &vnop_pageout_desc, (VOPFUNC)err_pageout },           /* Pageout */
-        { &vnop_copyfile_desc, (VOPFUNC)err_copyfile },                /* Copyfile */
-       { &vnop_blktooff_desc, (VOPFUNC)err_blktooff },         /* blktooff */
-       { &vnop_offtoblk_desc, (VOPFUNC)err_offtoblk },         /* offtoblk */
-       { &vnop_blockmap_desc, (VOPFUNC)err_blockmap },                 /* blockmap */
-       { (struct vnodeop_desc*)NULL, (int(*)())NULL }
+int(**fifo_vnodeop_p)(void *);
+const struct vnodeopv_entry_desc fifo_vnodeop_entries[] = {
+       { .opve_op = &vnop_default_desc, .opve_impl = (VOPFUNC)vn_default_error },
+       { .opve_op = &vnop_lookup_desc, .opve_impl = (VOPFUNC)fifo_lookup },            /* lookup */
+       { .opve_op = &vnop_create_desc, .opve_impl = (VOPFUNC)err_create },             /* create */
+       { .opve_op = &vnop_mknod_desc, .opve_impl = (VOPFUNC)err_mknod },               /* mknod */
+       { .opve_op = &vnop_open_desc, .opve_impl = (VOPFUNC)fifo_open },                        /* open */
+       { .opve_op = &vnop_close_desc, .opve_impl = (VOPFUNC)fifo_close },              /* close */
+       { .opve_op = &vnop_access_desc, .opve_impl = (VOPFUNC)fifo_access },            /* access */
+       { .opve_op = &vnop_getattr_desc, .opve_impl = (VOPFUNC)fifo_getattr },          /* getattr */
+       { .opve_op = &vnop_setattr_desc, .opve_impl = (VOPFUNC)fifo_setattr },          /* setattr */
+       { .opve_op = &vnop_read_desc, .opve_impl = (VOPFUNC)fifo_read },                        /* read */
+       { .opve_op = &vnop_write_desc, .opve_impl = (VOPFUNC)fifo_write },              /* write */
+       { .opve_op = &vnop_ioctl_desc, .opve_impl = (VOPFUNC)fifo_ioctl },              /* ioctl */
+       { .opve_op = &vnop_select_desc, .opve_impl = (VOPFUNC)fifo_select },            /* select */
+       { .opve_op = &vnop_revoke_desc, .opve_impl = (VOPFUNC)fifo_revoke },            /* revoke */
+       { .opve_op = &vnop_mmap_desc, .opve_impl = (VOPFUNC)err_mmap },                 /* mmap */
+       { .opve_op = &vnop_fsync_desc, .opve_impl = (VOPFUNC)fifo_fsync },              /* fsync */
+       { .opve_op = &vnop_remove_desc, .opve_impl = (VOPFUNC)err_remove },             /* remove */
+       { .opve_op = &vnop_link_desc, .opve_impl = (VOPFUNC)err_link },                 /* link */
+       { .opve_op = &vnop_rename_desc, .opve_impl = (VOPFUNC)err_rename },             /* rename */
+       { .opve_op = &vnop_mkdir_desc, .opve_impl = (VOPFUNC)err_mkdir },               /* mkdir */
+       { .opve_op = &vnop_rmdir_desc, .opve_impl = (VOPFUNC)err_rmdir },               /* rmdir */
+       { .opve_op = &vnop_symlink_desc, .opve_impl = (VOPFUNC)err_symlink },           /* symlink */
+       { .opve_op = &vnop_readdir_desc, .opve_impl = (VOPFUNC)err_readdir },           /* readdir */
+       { .opve_op = &vnop_readlink_desc, .opve_impl = (VOPFUNC)err_readlink },         /* readlink */
+       { .opve_op = &vnop_inactive_desc, .opve_impl = (VOPFUNC)fifo_inactive },                /* inactive */
+       { .opve_op = &vnop_reclaim_desc, .opve_impl = (VOPFUNC)fifo_reclaim },          /* reclaim */
+       { .opve_op = &vnop_strategy_desc, .opve_impl = (VOPFUNC)err_strategy },         /* strategy */
+       { .opve_op = &vnop_pathconf_desc, .opve_impl = (VOPFUNC)fifo_pathconf },                /* pathconf */
+       { .opve_op = &vnop_advlock_desc, .opve_impl = (VOPFUNC)fifo_advlock },          /* advlock */
+       { .opve_op = &vnop_bwrite_desc, .opve_impl = (VOPFUNC)fifo_bwrite },            /* bwrite */
+       { .opve_op = &vnop_pagein_desc, .opve_impl = (VOPFUNC)err_pagein },             /* Pagein */
+       { .opve_op = &vnop_pageout_desc, .opve_impl = (VOPFUNC)err_pageout },           /* Pageout */
+       { .opve_op = &vnop_copyfile_desc, .opve_impl = (VOPFUNC)err_copyfile },         /* Copyfile */
+       { .opve_op = &vnop_blktooff_desc, .opve_impl = (VOPFUNC)err_blktooff },         /* blktooff */
+       { .opve_op = &vnop_offtoblk_desc, .opve_impl = (VOPFUNC)err_offtoblk },         /* offtoblk */
+       { .opve_op = &vnop_blockmap_desc, .opve_impl = (VOPFUNC)err_blockmap },                 /* blockmap */
+       { .opve_op = (struct vnodeop_desc*)NULL, .opve_impl = (int (*)(void *))NULL }
 };
-struct vnodeopv_desc fifo_vnodeop_opv_desc =
-       { &fifo_vnodeop_p, fifo_vnodeop_entries };
+const struct vnodeopv_desc fifo_vnodeop_opv_desc =
+{ .opv_desc_vector_p = &fifo_vnodeop_p, .opv_desc_ops = fifo_vnodeop_entries };
 
 /*
  * Trivial lookup routine that always fails.
  */
 /* ARGSUSED */
 int
-fifo_lookup(ap)
-       struct vnop_lookup_args /* {
-               struct vnode * a_dvp;
-               struct vnode ** a_vpp;
-               struct componentname * a_cnp;
-               vfs_context_t a_context;
-       } */ *ap;
+fifo_lookup(struct vnop_lookup_args *ap)
 {
-       
        *ap->a_vpp = NULL;
-       return (ENOTDIR);
+       return ENOTDIR;
 }
 
 /*
@@ -151,12 +139,7 @@ fifo_lookup(ap)
  */
 /* ARGSUSED */
 int
-fifo_open(ap)
-       struct vnop_open_args /* {
-               struct vnode *a_vp;
-               int  a_mode;
-               vfs_context_t a_context;
-       } */ *ap;
+fifo_open(struct vnop_open_args *ap)
 {
        struct vnode *vp = ap->a_vp;
        struct fifoinfo *fip;
@@ -169,58 +152,57 @@ retry:
 
        fip = vp->v_fifoinfo;
 
-       if (fip == (struct fifoinfo *)0)
+       if (fip == (struct fifoinfo *)0) {
                panic("fifo_open with no fifoinfo");
+       }
 
        if ((fip->fi_flags & FIFO_CREATED) == 0) {
                if (fip->fi_flags & FIFO_INCREATE) {
-                       fip->fi_flags |= FIFO_CREATEWAIT;       
-                       error = msleep(&fip->fi_flags, &vp->v_lock, PRIBIO | PCATCH, "fifocreatewait", 0);
+                       fip->fi_flags |= FIFO_CREATEWAIT;
+                       error = msleep(&fip->fi_flags, &vp->v_lock, PRIBIO | PCATCH, "fifocreatewait", NULL);
                        if (error) {
                                vnode_unlock(vp);
-                               return(error);
+                               return error;
                        }
                        goto retry;
                } else {
-                       fip->fi_flags |= FIFO_INCREATE; 
+                       fip->fi_flags |= FIFO_INCREATE;
                        vnode_unlock(vp);
-                       if ( (error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0)) ) {
-                               goto bad1;
+                       if ((error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0))) {
+                               goto bad1;
                        }
-                       fip->fi_readsock = rso;
 
-                       if ( (error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0)) ) {
+                       if ((error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0))) {
                                (void)soclose(rso);
-                               goto bad1;
+                               goto bad1;
                        }
-                       fip->fi_writesock = wso;
 
-                       if ( (error = soconnect2(wso, rso)) ) {
+                       if ((error = soconnect2(wso, rso))) {
                                (void)soclose(wso);
                                (void)soclose(rso);
-                               goto bad1;
+                               goto bad1;
                        }
                        fip->fi_readers = fip->fi_writers = 0;
 
-               socket_lock(wso, 1);
+                       /* Lock ordering between wso and rso does not matter here
+                        * because they are just created and no one has a reference to them
+                        */
+                       socket_lock(wso, 1);
                        wso->so_state |= SS_CANTRCVMORE;
                        wso->so_snd.sb_lowat = PIPE_BUF;
-#if 0
-                       /* Because all the unp is protected by single mutex 
-                        * doing it in two step may actually cause problems
-                        * as it opens up window between the drop and acquire
-                        */
-               socket_unlock(wso, 1);
+                       socket_unlock(wso, 1);
 
-               socket_lock(rso, 1);
-#endif
+                       socket_lock(rso, 1);
                        rso->so_state |= SS_CANTSENDMORE;
-               socket_unlock(wso, 1);
+                       socket_unlock(rso, 1);
 
                        vnode_lock(vp);
+                       fip->fi_readsock = rso;
+                       fip->fi_writesock = wso;
+
                        fip->fi_flags |= FIFO_CREATED;
                        fip->fi_flags &= ~FIFO_INCREATE;
-                       
+
                        if ((fip->fi_flags & FIFO_CREATEWAIT)) {
                                fip->fi_flags &= ~FIFO_CREATEWAIT;
                                wakeup(&fip->fi_flags);
@@ -238,8 +220,9 @@ retry:
                        fip->fi_writesock->so_state &= ~SS_CANTSENDMORE;
                        socket_unlock(fip->fi_writesock, 1);
 
-                       if (fip->fi_writers > 0)
+                       if (fip->fi_writers > 0) {
                                wakeup((caddr_t)&fip->fi_writers);
+                       }
                }
        }
        if (ap->a_mode & FWRITE) {
@@ -248,95 +231,96 @@ retry:
                        socket_lock(fip->fi_readsock, 1);
                        fip->fi_readsock->so_state &= ~SS_CANTRCVMORE;
                        socket_unlock(fip->fi_readsock, 1);
-       
-                       if (fip->fi_readers > 0)
+
+                       if (fip->fi_readers > 0) {
                                wakeup((caddr_t)&fip->fi_readers);
+                       }
                }
        }
        if ((ap->a_mode & FREAD) && (ap->a_mode & O_NONBLOCK) == 0) {
                if (fip->fi_writers == 0) {
                        error = msleep((caddr_t)&fip->fi_readers, &vp->v_lock,
-                                       PCATCH | PSOCK, "fifoor", 0);
-                       if (error)
+                           PCATCH | PSOCK, "fifoor", NULL);
+                       if (error) {
                                goto bad;
+                       }
                        if (fip->fi_readers == 1) {
-                               if (fip->fi_writers > 0)
+                               if (fip->fi_writers > 0) {
                                        wakeup((caddr_t)&fip->fi_writers);
+                               }
                        }
                }
        }
        if (ap->a_mode & FWRITE) {
                if (ap->a_mode & O_NONBLOCK) {
                        if (fip->fi_readers == 0) {
-                                       error = ENXIO;
-                                       goto bad;
+                               error = ENXIO;
+                               goto bad;
                        }
                } else {
                        if (fip->fi_readers == 0) {
-                               error = msleep((caddr_t)&fip->fi_writers,&vp->v_lock,
-                                               PCATCH | PSOCK, "fifoow", 0);
-                               if (error)
+                               error = msleep((caddr_t)&fip->fi_writers, &vp->v_lock,
+                                   PCATCH | PSOCK, "fifoow", NULL);
+                               if (error) {
                                        goto bad;
+                               }
                                if (fip->fi_writers == 1) {
-                                       if (fip->fi_readers > 0)
+                                       if (fip->fi_readers > 0) {
                                                wakeup((caddr_t)&fip->fi_readers);
+                                       }
                                }
                        }
                }
        }
 
        vnode_unlock(vp);
-       return (0);
+       return 0;
 bad:
        fifo_close_internal(vp, ap->a_mode, ap->a_context, 1);
 
        vnode_unlock(vp);
-       return (error);
+       return error;
 bad1:
        vnode_lock(vp);
 
        fip->fi_flags &= ~FIFO_INCREATE;
-                       
+
        if ((fip->fi_flags & FIFO_CREATEWAIT)) {
                fip->fi_flags &= ~FIFO_CREATEWAIT;
                wakeup(&fip->fi_flags);
        }
        vnode_unlock(vp);
 
-       return (error);
+       return error;
 }
 
 /*
  * Vnode op for read
  */
 int
-fifo_read(ap)
-       struct vnop_read_args /* {
-               struct vnode *a_vp;
-               struct uio *a_uio;
-               int  a_ioflag;
-               vfs_context_t a_context;
-       } */ *ap;
+fifo_read(struct vnop_read_args *ap)
 {
        struct uio *uio = ap->a_uio;
        struct socket *rso = ap->a_vp->v_fifoinfo->fi_readsock;
-       int error, startresid;
+       user_ssize_t startresid;
+       int error;
        int rflags;
 
 #if DIAGNOSTIC
-       if (uio->uio_rw != UIO_READ)
+       if (uio->uio_rw != UIO_READ) {
                panic("fifo_read mode");
+       }
 #endif
-       if (uio_resid(uio) == 0)
-               return (0);
+       if (uio_resid(uio) == 0) {
+               return 0;
+       }
 
        rflags = (ap->a_ioflag & IO_NDELAY) ? MSG_NBIO : 0;
 
-       // LP64todo - fix this!
        startresid = uio_resid(uio);
 
-       /* fifo conformance - if we have a reader open on the fifo but no 
-        * writers then we need to make sure we do not block.  We do that by 
+       /* fifo conformance - if we have a reader open on the fifo but no
+        * writers then we need to make sure we do not block.  We do that by
         * checking the receive buffer and if empty set error to EWOULDBLOCK.
         * If error is set to EWOULDBLOCK we skip the call into soreceive
         */
@@ -350,9 +334,11 @@ fifo_read(ap)
        /* skip soreceive to avoid blocking when we have no writers */
        if (error != EWOULDBLOCK) {
                error = soreceive(rso, (struct sockaddr **)0, uio, (struct mbuf **)0,
-                                               (struct mbuf **)0, &rflags);
-       }
-       else {
+                   (struct mbuf **)0, &rflags);
+               if (error == 0) {
+                       lock_vnode_and_post(ap->a_vp, 0);
+               }
+       } else {
                /* clear EWOULDBLOCK and return EOF (zero) */
                error = 0;
        }
@@ -364,82 +350,67 @@ fifo_read(ap)
                rso->so_state &= ~SS_CANTRCVMORE;
                socket_unlock(rso, 1);
        }
-       return (error);
+       return error;
 }
 
 /*
  * Vnode op for write
  */
 int
-fifo_write(ap)
-       struct vnop_write_args /* {
-               struct vnode *a_vp;
-               struct uio *a_uio;
-               int  a_ioflag;
-               vfs_context_t a_context;
-       } */ *ap;
+fifo_write(struct vnop_write_args *ap)
 {
        struct socket *wso = ap->a_vp->v_fifoinfo->fi_writesock;
        int error;
 
 #if DIAGNOSTIC
-       if (ap->a_uio->uio_rw != UIO_WRITE)
+       if (ap->a_uio->uio_rw != UIO_WRITE) {
                panic("fifo_write mode");
+       }
 #endif
-       error = sosend(wso, (struct sockaddr *)0, ap->a_uio, 0,
-                      (struct mbuf *)0, (ap->a_ioflag & IO_NDELAY) ? MSG_NBIO : 0);
+       error = sosend(wso, (struct sockaddr *)0, ap->a_uio, NULL,
+           (struct mbuf *)0, (ap->a_ioflag & IO_NDELAY) ? MSG_NBIO : 0);
+       if (error == 0) {
+               lock_vnode_and_post(ap->a_vp, 0);
+       }
 
-       return (error);
+       return error;
 }
 
 /*
  * Device ioctl operation.
  */
 int
-fifo_ioctl(ap)
-       struct vnop_ioctl_args /* {
-               struct vnode *a_vp;
-               int  a_command;
-               caddr_t  a_data;
-               int  a_fflag;
-               vfs_context_t a_context;
-       } */ *ap;
+fifo_ioctl(struct vnop_ioctl_args *ap)
 {
-       struct proc *p = vfs_context_proc(ap->a_context);
        struct fileproc filetmp;
        struct fileglob filefg;
        int error;
 
-       if (ap->a_command == FIONBIO)
-               return (0);
+       if (ap->a_command == FIONBIO) {
+               return 0;
+       }
        bzero(&filetmp, sizeof(struct fileproc));
        filetmp.f_fglob = &filefg;
        if (ap->a_fflag & FREAD) {
                filetmp.f_fglob->fg_data = (caddr_t)ap->a_vp->v_fifoinfo->fi_readsock;
-               error = soo_ioctl(&filetmp, ap->a_command, ap->a_data, p);
-               if (error)
-                       return (error);
+               error = soo_ioctl(&filetmp, ap->a_command, ap->a_data, ap->a_context);
+               if (error) {
+                       return error;
+               }
        }
        if (ap->a_fflag & FWRITE) {
                filetmp.f_fglob->fg_data = (caddr_t)ap->a_vp->v_fifoinfo->fi_writesock;
-               error = soo_ioctl(&filetmp, ap->a_command, ap->a_data, p);
-               if (error)
-                       return (error);
+               error = soo_ioctl(&filetmp, ap->a_command, ap->a_data, ap->a_context);
+               if (error) {
+                       return error;
+               }
        }
-       return (0);
+       return 0;
 }
 
 int
-fifo_select(ap)
-       struct vnop_select_args /* {
-               struct vnode *a_vp;
-               int  a_which;
-               int  a_fflags;
-               void * a_wql;
-               vfs_context_t a_context;
-       } */ *ap;
+fifo_select(struct vnop_select_args *ap)
 {
-       struct proc *p = vfs_context_proc(ap->a_context);
        struct fileproc filetmp;
        struct fileglob filefg;
        int ready;
@@ -448,23 +419,25 @@ fifo_select(ap)
        filetmp.f_fglob = &filefg;
        if (ap->a_which & FREAD) {
                filetmp.f_fglob->fg_data = (caddr_t)ap->a_vp->v_fifoinfo->fi_readsock;
-               ready = soo_select(&filetmp, ap->a_which, ap->a_wql, p);
-               if (ready)
-                       return (ready);
+               ready = soo_select(&filetmp, ap->a_which, ap->a_wql, ap->a_context);
+               if (ready) {
+                       return ready;
+               }
        }
        if (ap->a_which & FWRITE) {
                filetmp.f_fglob->fg_data = (caddr_t)ap->a_vp->v_fifoinfo->fi_writesock;
-               ready = soo_select(&filetmp, ap->a_which, ap->a_wql, p);
-               if (ready)
-                       return (ready);
+               ready = soo_select(&filetmp, ap->a_which, ap->a_wql, ap->a_context);
+               if (ready) {
+                       return ready;
+               }
        }
-       return (0);
+       return 0;
 }
 
 int
 fifo_inactive(__unused struct vnop_inactive_args *ap)
 {
-       return (0);
+       return 0;
 }
 
 
@@ -472,12 +445,7 @@ fifo_inactive(__unused struct vnop_inactive_args *ap)
  * Device close routine
  */
 int
-fifo_close(ap)
-       struct vnop_close_args /* {
-               struct vnode *a_vp;
-               int  a_fflag;
-               vfs_context_t a_context;
-       } */ *ap;
+fifo_close(struct vnop_close_args *ap)
 {
        return fifo_close_internal(ap->a_vp, ap->a_fflag, ap->a_context, 0);
 }
@@ -485,24 +453,25 @@ fifo_close(ap)
 int
 fifo_close_internal(vnode_t vp, int fflag, __unused vfs_context_t context, int locked)
 {
-       register struct fifoinfo *fip = vp->v_fifoinfo;
+       struct fifoinfo *fip = vp->v_fifoinfo;
        int error1, error2;
        struct socket *rso;
        struct socket *wso;
 
-       if (!locked)
+       if (!locked) {
                vnode_lock(vp);
+       }
 
        if ((fip->fi_flags & FIFO_CREATED) == 0) {
-               if (!locked)
+               if (!locked) {
                        vnode_unlock(vp);
-               return(0);
-
+               }
+               return 0;
        }
-               
+
        if (fflag & FREAD) {
                fip->fi_readers--;
-               if (fip->fi_readers == 0){
+               if (fip->fi_readers == 0) {
                        socket_lock(fip->fi_writesock, 1);
                        socantsendmore(fip->fi_writesock);
                        socket_unlock(fip->fi_writesock, 1);
@@ -519,72 +488,67 @@ fifo_close_internal(vnode_t vp, int fflag, __unused vfs_context_t context, int l
        }
 #if 0
        if (vnode_isinuse_locked(vp, 0, 1)) {
-               if (!locked)
+               if (!locked) {
                        vnode_unlock(vp);
-               return (0);
+               }
+               return 0;
        }
 #endif
 
        if (fip->fi_writers || fip->fi_readers) {
-               if (!locked)
+               if (!locked) {
                        vnode_unlock(vp);
-               return (0);
+               }
+               return 0;
        }
 
        wso = fip->fi_writesock;
        rso = fip->fi_readsock;
-       fip->fi_readsock = 0;
-       fip->fi_writesock = 0;
+       fip->fi_readsock = NULL;
+       fip->fi_writesock = NULL;
        fip->fi_flags &= ~FIFO_CREATED;
-       if (!locked)
+       if (!locked) {
                vnode_unlock(vp);
+       }
        error1 = soclose(rso);
        error2 = soclose(wso);
 
-       if (error1)
-               return (error1);
-       return (error2);
+       if (error1) {
+               return error1;
+       }
+       return error2;
 }
 
-
 /*
  * Print out internal contents of a fifo vnode.
  */
 void
-fifo_printinfo(vp)
-       struct vnode *vp;
+fifo_printinfo(struct vnode *vp)
 {
-       register struct fifoinfo *fip = vp->v_fifoinfo;
+       struct fifoinfo *fip = vp->v_fifoinfo;
 
-       printf(", fifo with %d readers and %d writers",
-               fip->fi_readers, fip->fi_writers);
+       printf(", fifo with %ld readers and %ld writers",
+           fip->fi_readers, fip->fi_writers);
 }
 
 /*
  * Return POSIX pathconf information applicable to fifo's.
  */
 int
-fifo_pathconf(ap)
-       struct vnop_pathconf_args /* {
-               struct vnode *a_vp;
-               int a_name;
-               int *a_retval;
-               vfs_context_t a_context;
-       } */ *ap;
+fifo_pathconf(struct vnop_pathconf_args *ap)
 {
-
        switch (ap->a_name) {
        case _PC_LINK_MAX:
                *ap->a_retval = LINK_MAX;
-               return (0);
+               return 0;
        case _PC_PIPE_BUF:
                *ap->a_retval = PIPE_BUF;
-               return (0);
+               return 0;
        case _PC_CHOWN_RESTRICTED:
-               *ap->a_retval = 1;
-               return (0);
+               *ap->a_retval = 200112;         /* _POSIX_CHOWN_RESTRICTED */
+               return 0;
        default:
-               return (EINVAL);
+               return EINVAL;
        }
        /* NOTREACHED */
 }
@@ -595,8 +559,7 @@ fifo_pathconf(ap)
 int
 fifo_ebadf(__unused void *dummy)
 {
-
-       return (EBADF);
+       return EBADF;
 }
 
 /*
@@ -605,7 +568,29 @@ fifo_ebadf(__unused void *dummy)
 int
 fifo_advlock(__unused struct vnop_advlock_args *ap)
 {
+       return ENOTSUP;
+}
+
 
-       return (ENOTSUP);
+/* You'd certainly better have an iocount on the vnode! */
+int
+fifo_freespace(struct vnode *vp, long *count)
+{
+       struct socket *rsock;
+       rsock = vp->v_fifoinfo->fi_readsock;
+       socket_lock(rsock, 1);
+       *count = sbspace(&rsock->so_rcv);
+       socket_unlock(rsock, 1);
+       return 0;
 }
 
+int
+fifo_charcount(struct vnode *vp, int *count)
+{
+       int mcount;
+       int err = sock_ioctl(vp->v_fifoinfo->fi_readsock, FIONREAD, (void*)&mcount);
+       if (err == 0) {
+               *count = mcount;
+       }
+       return err;
+}