LCOV - code coverage report
Current view: top level - miscfs/fifofs - fifo_vnops.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 260 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 19 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: fifo_vnops.c,v 1.68 2018/07/30 12:22:14 mpi Exp $     */
       2             : /*      $NetBSD: fifo_vnops.c,v 1.18 1996/03/16 23:52:42 christos Exp $ */
       3             : 
       4             : /*
       5             :  * Copyright (c) 1990, 1993
       6             :  *      The Regents of the University of California.  All rights reserved.
       7             :  *
       8             :  * Redistribution and use in source and binary forms, with or without
       9             :  * modification, are permitted provided that the following conditions
      10             :  * are met:
      11             :  * 1. Redistributions of source code must retain the above copyright
      12             :  *    notice, this list of conditions and the following disclaimer.
      13             :  * 2. Redistributions in binary form must reproduce the above copyright
      14             :  *    notice, this list of conditions and the following disclaimer in the
      15             :  *    documentation and/or other materials provided with the distribution.
      16             :  * 3. Neither the name of the University nor the names of its contributors
      17             :  *    may be used to endorse or promote products derived from this software
      18             :  *    without specific prior written permission.
      19             :  *
      20             :  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
      21             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      22             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      23             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
      24             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      25             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      26             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      27             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      28             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      29             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      30             :  * SUCH DAMAGE.
      31             :  *
      32             :  *      @(#)fifo_vnops.c        8.4 (Berkeley) 8/10/94
      33             :  */
      34             : 
      35             : #include <sys/param.h>
      36             : #include <sys/systm.h>
      37             : #include <sys/time.h>
      38             : #include <sys/namei.h>
      39             : #include <sys/vnode.h>
      40             : #include <sys/lock.h>
      41             : #include <sys/protosw.h>
      42             : #include <sys/socket.h>
      43             : #include <sys/socketvar.h>
      44             : #include <sys/stat.h>
      45             : #include <sys/ioctl.h>
      46             : #include <sys/fcntl.h>
      47             : #include <sys/file.h>
      48             : #include <sys/event.h>
      49             : #include <sys/errno.h>
      50             : #include <sys/malloc.h>
      51             : #include <sys/poll.h>
      52             : #include <sys/unistd.h>
      53             : 
      54             : #include <miscfs/fifofs/fifo.h>
      55             : 
      56             : /*
      57             :  * This structure is associated with the FIFO vnode and stores
      58             :  * the state associated with the FIFO.
      59             :  */
      60             : struct fifoinfo {
      61             :         struct socket   *fi_readsock;
      62             :         struct socket   *fi_writesock;
      63             :         long            fi_readers;
      64             :         long            fi_writers;
      65             : };
      66             : 
      67             : struct vops fifo_vops = {
      68             :         .vop_lookup     = vop_generic_lookup,
      69             :         .vop_create     = fifo_badop,
      70             :         .vop_mknod      = fifo_badop,
      71             :         .vop_open       = fifo_open,
      72             :         .vop_close      = fifo_close,
      73             :         .vop_access     = fifo_ebadf,
      74             :         .vop_getattr    = fifo_ebadf,
      75             :         .vop_setattr    = fifo_ebadf,
      76             :         .vop_read       = fifo_read,
      77             :         .vop_write      = fifo_write,
      78             :         .vop_ioctl      = fifo_ioctl,
      79             :         .vop_poll       = fifo_poll,
      80             :         .vop_kqfilter   = fifo_kqfilter,
      81             :         .vop_revoke     = vop_generic_revoke,
      82             :         .vop_fsync      = nullop,
      83             :         .vop_remove     = fifo_badop,
      84             :         .vop_link       = fifo_badop,
      85             :         .vop_rename     = fifo_badop,
      86             :         .vop_mkdir      = fifo_badop,
      87             :         .vop_rmdir      = fifo_badop,
      88             :         .vop_symlink    = fifo_badop,
      89             :         .vop_readdir    = fifo_badop,
      90             :         .vop_readlink   = fifo_badop,
      91             :         .vop_abortop    = fifo_badop,
      92             :         .vop_inactive   = fifo_inactive,
      93             :         .vop_reclaim    = fifo_reclaim,
      94             :         .vop_lock       = vop_generic_lock,
      95             :         .vop_unlock     = vop_generic_unlock,
      96             :         .vop_bmap       = vop_generic_bmap,
      97             :         .vop_strategy   = fifo_badop,
      98             :         .vop_print      = fifo_print,
      99             :         .vop_islocked   = vop_generic_islocked,
     100             :         .vop_pathconf   = fifo_pathconf,
     101             :         .vop_advlock    = fifo_advlock,
     102             :         .vop_bwrite     = nullop
     103             : };
     104             : 
     105             : void    filt_fifordetach(struct knote *kn);
     106             : int     filt_fiforead(struct knote *kn, long hint);
     107             : void    filt_fifowdetach(struct knote *kn);
     108             : int     filt_fifowrite(struct knote *kn, long hint);
     109             : 
     110             : struct filterops fiforead_filtops =
     111             :         { 1, NULL, filt_fifordetach, filt_fiforead };
     112             : struct filterops fifowrite_filtops =
     113             :         { 1, NULL, filt_fifowdetach, filt_fifowrite };
     114             : 
     115             : /*
     116             :  * Open called to set up a new instance of a fifo or
     117             :  * to find an active instance of a fifo.
     118             :  */
     119             : /* ARGSUSED */
     120             : int
     121           0 : fifo_open(void *v)
     122             : {
     123           0 :         struct vop_open_args *ap = v;
     124           0 :         struct vnode *vp = ap->a_vp;
     125             :         struct fifoinfo *fip;
     126           0 :         struct socket *rso, *wso;
     127             :         int s, error;
     128             : 
     129           0 :         if ((fip = vp->v_fifoinfo) == NULL) {
     130           0 :                 fip = malloc(sizeof(*fip), M_VNODE, M_WAITOK);
     131           0 :                 vp->v_fifoinfo = fip;
     132           0 :                 if ((error = socreate(AF_UNIX, &rso, SOCK_STREAM, 0)) != 0) {
     133           0 :                         free(fip, M_VNODE, sizeof *fip);
     134           0 :                         vp->v_fifoinfo = NULL;
     135           0 :                         return (error);
     136             :                 }
     137           0 :                 fip->fi_readsock = rso;
     138           0 :                 if ((error = socreate(AF_UNIX, &wso, SOCK_STREAM, 0)) != 0) {
     139           0 :                         (void)soclose(rso, 0);
     140           0 :                         free(fip, M_VNODE, sizeof *fip);
     141           0 :                         vp->v_fifoinfo = NULL;
     142           0 :                         return (error);
     143             :                 }
     144           0 :                 fip->fi_writesock = wso;
     145           0 :                 if ((error = soconnect2(wso, rso)) != 0) {
     146           0 :                         (void)soclose(wso, 0);
     147           0 :                         (void)soclose(rso, 0);
     148           0 :                         free(fip, M_VNODE, sizeof *fip);
     149           0 :                         vp->v_fifoinfo = NULL;
     150           0 :                         return (error);
     151             :                 }
     152           0 :                 fip->fi_readers = fip->fi_writers = 0;
     153           0 :                 s = solock(wso);
     154           0 :                 wso->so_state |= SS_CANTSENDMORE;
     155           0 :                 wso->so_snd.sb_lowat = PIPE_BUF;
     156           0 :         } else {
     157           0 :                 rso = fip->fi_readsock;
     158           0 :                 wso = fip->fi_writesock;
     159           0 :                 s = solock(wso);
     160             :         }
     161           0 :         if (ap->a_mode & FREAD) {
     162           0 :                 fip->fi_readers++;
     163           0 :                 if (fip->fi_readers == 1) {
     164           0 :                         wso->so_state &= ~SS_CANTSENDMORE;
     165           0 :                         if (fip->fi_writers > 0)
     166           0 :                                 wakeup(&fip->fi_writers);
     167             :                 }
     168             :         }
     169           0 :         if (ap->a_mode & FWRITE) {
     170           0 :                 fip->fi_writers++;
     171           0 :                 if ((ap->a_mode & O_NONBLOCK) && fip->fi_readers == 0) {
     172             :                         error = ENXIO;
     173           0 :                         sounlock(wso, s);
     174           0 :                         goto bad;
     175             :                 }
     176           0 :                 if (fip->fi_writers == 1) {
     177           0 :                         rso->so_state &= ~(SS_CANTRCVMORE|SS_ISDISCONNECTED);
     178           0 :                         if (fip->fi_readers > 0)
     179           0 :                                 wakeup(&fip->fi_readers);
     180             :                 }
     181             :         }
     182           0 :         sounlock(wso, s);
     183           0 :         if ((ap->a_mode & O_NONBLOCK) == 0) {
     184           0 :                 if ((ap->a_mode & FREAD) && fip->fi_writers == 0) {
     185           0 :                         VOP_UNLOCK(vp);
     186           0 :                         error = tsleep(&fip->fi_readers,
     187             :                             PCATCH | PSOCK, "fifor", 0);
     188           0 :                         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
     189           0 :                         if (error)
     190             :                                 goto bad;
     191             :                 }
     192           0 :                 if ((ap->a_mode & FWRITE) && fip->fi_readers == 0) {
     193           0 :                         VOP_UNLOCK(vp);
     194           0 :                         error = tsleep(&fip->fi_writers,
     195             :                             PCATCH | PSOCK, "fifow", 0);
     196           0 :                         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
     197           0 :                         if (error)
     198             :                                 goto bad;
     199             :                 }
     200             :         }
     201           0 :         return (0);
     202             : bad:
     203           0 :         VOP_CLOSE(vp, ap->a_mode, ap->a_cred, ap->a_p);
     204           0 :         return (error);
     205           0 : }
     206             : 
     207             : /*
     208             :  * Vnode op for read
     209             :  */
     210             : /* ARGSUSED */
     211             : int
     212           0 : fifo_read(void *v)
     213             : {
     214           0 :         struct vop_read_args *ap = v;
     215           0 :         struct uio *uio = ap->a_uio;
     216           0 :         struct socket *rso = ap->a_vp->v_fifoinfo->fi_readsock;
     217           0 :         int error, flags = 0;
     218             : 
     219             : #ifdef DIAGNOSTIC
     220           0 :         if (uio->uio_rw != UIO_READ)
     221           0 :                 panic("fifo_read mode");
     222             : #endif
     223           0 :         if (uio->uio_resid == 0)
     224           0 :                 return (0);
     225           0 :         if (ap->a_ioflag & IO_NDELAY)
     226           0 :                 flags |= MSG_DONTWAIT;
     227           0 :         VOP_UNLOCK(ap->a_vp);
     228           0 :         error = soreceive(rso, NULL, uio, NULL, NULL, &flags, 0);
     229           0 :         vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
     230           0 :         if (ap->a_ioflag & IO_NDELAY) {
     231           0 :                 if (error == EWOULDBLOCK &&
     232           0 :                     ap->a_vp->v_fifoinfo->fi_writers == 0)
     233           0 :                         error = 0;
     234             :         }
     235           0 :         return (error);
     236           0 : }
     237             : 
     238             : /*
     239             :  * Vnode op for write
     240             :  */
     241             : /* ARGSUSED */
     242             : int
     243           0 : fifo_write(void *v)
     244             : {
     245           0 :         struct vop_write_args *ap = v;
     246           0 :         struct socket *wso = ap->a_vp->v_fifoinfo->fi_writesock;
     247             :         int error, flags = 0;
     248             : 
     249             : #ifdef DIAGNOSTIC
     250           0 :         if (ap->a_uio->uio_rw != UIO_WRITE)
     251           0 :                 panic("fifo_write mode");
     252             : #endif
     253           0 :         if (ap->a_ioflag & IO_NDELAY)
     254           0 :                 flags |= MSG_DONTWAIT;
     255           0 :         VOP_UNLOCK(ap->a_vp);
     256           0 :         error = sosend(wso, NULL, ap->a_uio, NULL, NULL, flags);
     257           0 :         vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
     258           0 :         return (error);
     259             : }
     260             : 
     261             : /*
     262             :  * Device ioctl operation.
     263             :  */
     264             : /* ARGSUSED */
     265             : int
     266           0 : fifo_ioctl(void *v)
     267             : {
     268           0 :         struct vop_ioctl_args *ap = v;
     269           0 :         struct file filetmp;
     270             :         int error;
     271             : 
     272           0 :         if (ap->a_command == FIONBIO)
     273           0 :                 return (0);
     274           0 :         if (ap->a_fflag & FREAD) {
     275           0 :                 filetmp.f_data = ap->a_vp->v_fifoinfo->fi_readsock;
     276           0 :                 error = soo_ioctl(&filetmp, ap->a_command, ap->a_data, ap->a_p);
     277           0 :                 if (error)
     278           0 :                         return (error);
     279             :         }
     280           0 :         if (ap->a_fflag & FWRITE) {
     281           0 :                 filetmp.f_data = ap->a_vp->v_fifoinfo->fi_writesock;
     282           0 :                 error = soo_ioctl(&filetmp, ap->a_command, ap->a_data, ap->a_p);
     283           0 :                 if (error)
     284           0 :                         return (error);
     285             :         }
     286           0 :         return (0);
     287           0 : }
     288             : 
     289             : /* ARGSUSED */
     290             : int
     291           0 : fifo_poll(void *v)
     292             : {
     293           0 :         struct vop_poll_args *ap = v;
     294           0 :         struct socket *rso = ap->a_vp->v_fifoinfo->fi_readsock;
     295           0 :         struct socket *wso = ap->a_vp->v_fifoinfo->fi_writesock;
     296             :         int events = 0;
     297             :         int revents = 0;
     298             :         int s;
     299             : 
     300             :         /*
     301             :          * FIFOs don't support out-of-band or high priority data.
     302             :          */
     303           0 :         s = solock(rso);
     304           0 :         if (ap->a_fflag & FREAD)
     305           0 :                 events |= ap->a_events & (POLLIN | POLLRDNORM);
     306           0 :         if (ap->a_fflag & FWRITE)
     307           0 :                 events |= ap->a_events & (POLLOUT | POLLWRNORM);
     308             : 
     309           0 :         if (events & (POLLIN | POLLRDNORM)) {
     310           0 :                 if (soreadable(rso))
     311           0 :                         revents |= events & (POLLIN | POLLRDNORM);
     312             :         }
     313             :         /* NOTE: POLLHUP and POLLOUT/POLLWRNORM are mutually exclusive */
     314           0 :         if ((rso->so_state & SS_ISDISCONNECTED) && !(ap->a_events & POLL_NOHUP)) {
     315           0 :                 revents |= POLLHUP;
     316           0 :         } else if (events & (POLLOUT | POLLWRNORM)) {
     317           0 :                 if (sowriteable(wso))
     318           0 :                         revents |= events & (POLLOUT | POLLWRNORM);
     319             :         }
     320           0 :         if (revents == 0) {
     321             :                 /* We want to return POLLHUP even if no valid events set. */
     322           0 :                 if (events == 0 && !(ap->a_events & POLL_NOHUP))
     323           0 :                         events = POLLIN;
     324           0 :                 if (events & (POLLIN | POLLRDNORM)) {
     325           0 :                         selrecord(ap->a_p, &rso->so_rcv.sb_sel);
     326           0 :                         rso->so_rcv.sb_flags |= SB_SEL;
     327           0 :                 }
     328           0 :                 if (events & (POLLOUT | POLLWRNORM)) {
     329           0 :                         selrecord(ap->a_p, &wso->so_snd.sb_sel);
     330           0 :                         wso->so_snd.sb_flags |= SB_SEL;
     331           0 :                 }
     332             :         }
     333           0 :         sounlock(rso, s);
     334           0 :         return (revents);
     335             : }
     336             : 
     337             : int
     338           0 : fifo_inactive(void *v)
     339             : {
     340           0 :         struct vop_inactive_args *ap = v;
     341             : 
     342           0 :         VOP_UNLOCK(ap->a_vp);
     343           0 :         return (0);
     344             : }
     345             : 
     346             : 
     347             : /*
     348             :  * Device close routine
     349             :  */
     350             : /* ARGSUSED */
     351             : int
     352           0 : fifo_close(void *v)
     353             : {
     354           0 :         struct vop_close_args *ap = v;
     355           0 :         struct vnode *vp = ap->a_vp;
     356           0 :         struct fifoinfo *fip = vp->v_fifoinfo;
     357             :         int s, error1 = 0, error2 = 0;
     358             : 
     359           0 :         if (fip == NULL)
     360           0 :                 return (0);
     361             : 
     362           0 :         if (ap->a_fflag & FREAD) {
     363           0 :                 if (--fip->fi_readers == 0) {
     364           0 :                         struct socket *wso = fip->fi_writesock;
     365             : 
     366           0 :                         s = solock(wso);
     367           0 :                         socantsendmore(wso);
     368           0 :                         sounlock(wso, s);
     369           0 :                 }
     370             :         }
     371           0 :         if (ap->a_fflag & FWRITE) {
     372           0 :                 if (--fip->fi_writers == 0) {
     373           0 :                         struct socket *rso = fip->fi_readsock;
     374             : 
     375           0 :                         s = solock(rso);
     376             :                         /* SS_ISDISCONNECTED will result in POLLHUP */
     377           0 :                         rso->so_state |= SS_ISDISCONNECTED;
     378           0 :                         socantrcvmore(rso);
     379           0 :                         sounlock(rso, s);
     380           0 :                 }
     381             :         }
     382           0 :         if (fip->fi_readers == 0 && fip->fi_writers == 0) {
     383           0 :                 error1 = soclose(fip->fi_readsock, 0);
     384           0 :                 error2 = soclose(fip->fi_writesock, 0);
     385           0 :                 free(fip, M_VNODE, sizeof *fip);
     386           0 :                 vp->v_fifoinfo = NULL;
     387           0 :         }
     388           0 :         return (error1 ? error1 : error2);
     389           0 : }
     390             : 
     391             : int
     392           0 : fifo_reclaim(void *v)
     393             : {
     394           0 :         struct vop_reclaim_args *ap = v;
     395           0 :         struct vnode *vp = ap->a_vp;
     396           0 :         struct fifoinfo *fip = vp->v_fifoinfo;
     397             : 
     398           0 :         if (fip == NULL)
     399           0 :                 return (0);
     400             : 
     401           0 :         soclose(fip->fi_readsock, 0);
     402           0 :         soclose(fip->fi_writesock, 0);
     403           0 :         free(fip, M_VNODE, sizeof *fip);
     404           0 :         vp->v_fifoinfo = NULL;
     405             : 
     406           0 :         return (0);
     407           0 : }
     408             : 
     409             : /*
     410             :  * Print out the contents of a fifo vnode.
     411             :  */
     412             : int
     413           0 : fifo_print(void *v)
     414             : {
     415           0 :         struct vop_print_args *ap = v;
     416             : 
     417           0 :         printf("tag VT_NON");
     418           0 :         fifo_printinfo(ap->a_vp);
     419           0 :         printf("\n");
     420           0 :         return 0;
     421             : }
     422             : 
     423             : /*
     424             :  * Print out internal contents of a fifo vnode.
     425             :  */
     426             : void
     427           0 : fifo_printinfo(struct vnode *vp)
     428             : {
     429           0 :         struct fifoinfo *fip = vp->v_fifoinfo;
     430             : 
     431           0 :         printf(", fifo with %ld readers and %ld writers",
     432           0 :                 fip->fi_readers, fip->fi_writers);
     433           0 : }
     434             : 
     435             : /*
     436             :  * Return POSIX pathconf information applicable to fifo's.
     437             :  */
     438             : int
     439           0 : fifo_pathconf(void *v)
     440             : {
     441           0 :         struct vop_pathconf_args *ap = v;
     442             :         int error = 0;
     443             : 
     444           0 :         switch (ap->a_name) {
     445             :         case _PC_LINK_MAX:
     446           0 :                 *ap->a_retval = LINK_MAX;
     447           0 :                 break;
     448             :         case _PC_CHOWN_RESTRICTED:
     449           0 :                 *ap->a_retval = 1;
     450           0 :                 break;
     451             :         case _PC_TIMESTAMP_RESOLUTION:
     452           0 :                 *ap->a_retval = 1;
     453           0 :                 break;
     454             :         default:
     455             :                 error = EINVAL;
     456           0 :                 break;
     457             :         }
     458             : 
     459           0 :         return (error);
     460             : }
     461             : 
     462             : /*
     463             :  * Fifo failed operation
     464             :  */
     465             : /*ARGSUSED*/
     466             : int
     467           0 : fifo_ebadf(void *v)
     468             : {
     469             : 
     470           0 :         return (EBADF);
     471             : }
     472             : 
     473             : /*
     474             :  * Fifo advisory byte-level locks.
     475             :  */
     476             : /* ARGSUSED */
     477             : int
     478           0 : fifo_advlock(void *v)
     479             : {
     480           0 :         return (EOPNOTSUPP);
     481             : }
     482             : 
     483             : /*
     484             :  * Fifo bad operation
     485             :  */
     486             : /*ARGSUSED*/
     487             : int
     488           0 : fifo_badop(void *v)
     489             : {
     490             : 
     491           0 :         panic("fifo_badop called");
     492             :         /* NOTREACHED */
     493             :         return(0);
     494             : }
     495             : 
     496             : 
     497             : int
     498           0 : fifo_kqfilter(void *v)
     499             : {
     500           0 :         struct vop_kqfilter_args *ap = v;
     501           0 :         struct socket *so = (struct socket *)ap->a_vp->v_fifoinfo->fi_readsock;
     502             :         struct sockbuf *sb;
     503             : 
     504           0 :         switch (ap->a_kn->kn_filter) {
     505             :         case EVFILT_READ:
     506           0 :                 ap->a_kn->kn_fop = &fiforead_filtops;
     507           0 :                 sb = &so->so_rcv;
     508           0 :                 break;
     509             :         case EVFILT_WRITE:
     510           0 :                 ap->a_kn->kn_fop = &fifowrite_filtops;
     511           0 :                 sb = &so->so_snd;
     512           0 :                 break;
     513             :         default:
     514           0 :                 return (EINVAL);
     515             :         }
     516             : 
     517           0 :         ap->a_kn->kn_hook = so;
     518             : 
     519           0 :         SLIST_INSERT_HEAD(&sb->sb_sel.si_note, ap->a_kn, kn_selnext);
     520           0 :         sb->sb_flagsintr |= SB_KNOTE;
     521             : 
     522           0 :         return (0);
     523           0 : }
     524             : 
     525             : void
     526           0 : filt_fifordetach(struct knote *kn)
     527             : {
     528           0 :         struct socket *so = (struct socket *)kn->kn_hook;
     529             : 
     530           0 :         SLIST_REMOVE(&so->so_rcv.sb_sel.si_note, kn, knote, kn_selnext);
     531           0 :         if (SLIST_EMPTY(&so->so_rcv.sb_sel.si_note))
     532           0 :                 so->so_rcv.sb_flagsintr &= ~SB_KNOTE;
     533           0 : }
     534             : 
     535             : int
     536           0 : filt_fiforead(struct knote *kn, long hint)
     537             : {
     538           0 :         struct socket *so = (struct socket *)kn->kn_hook;
     539             :         int rv;
     540             : 
     541           0 :         kn->kn_data = so->so_rcv.sb_cc;
     542           0 :         if (so->so_state & SS_CANTRCVMORE) {
     543           0 :                 kn->kn_flags |= EV_EOF;
     544             :                 rv = 1;
     545           0 :         } else {
     546           0 :                 kn->kn_flags &= ~EV_EOF;
     547           0 :                 rv = (kn->kn_data > 0);
     548             :         }
     549             : 
     550           0 :         return (rv);
     551             : }
     552             : 
     553             : void
     554           0 : filt_fifowdetach(struct knote *kn)
     555             : {
     556           0 :         struct socket *so = (struct socket *)kn->kn_hook;
     557             : 
     558           0 :         SLIST_REMOVE(&so->so_snd.sb_sel.si_note, kn, knote, kn_selnext);
     559           0 :         if (SLIST_EMPTY(&so->so_snd.sb_sel.si_note))
     560           0 :                 so->so_snd.sb_flagsintr &= ~SB_KNOTE;
     561           0 : }
     562             : 
     563             : int
     564           0 : filt_fifowrite(struct knote *kn, long hint)
     565             : {
     566           0 :         struct socket *so = (struct socket *)kn->kn_hook;
     567             :         int rv;
     568             : 
     569           0 :         kn->kn_data = sbspace(so, &so->so_snd);
     570           0 :         if (so->so_state & SS_CANTSENDMORE) {
     571           0 :                 kn->kn_flags |= EV_EOF;
     572             :                 rv = 1;
     573           0 :         } else {
     574           0 :                 kn->kn_flags &= ~EV_EOF;
     575           0 :                 rv = (kn->kn_data >= so->so_snd.sb_lowat);
     576             :         }
     577             : 
     578           0 :         return (rv);
     579             : }

Generated by: LCOV version 1.13