The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/fifofs/fifo_vnops.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1990, 1993, 1995
    3  *      The Regents of the University of California.  All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 4. Neither the name of the University nor the names of its contributors
   14  *    may be used to endorse or promote products derived from this software
   15  *    without specific prior written permission.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27  * SUCH DAMAGE.
   28  *
   29  *      @(#)fifo_vnops.c        8.10 (Berkeley) 5/27/95
   30  * $FreeBSD: src/sys/fs/fifofs/fifo_vnops.c,v 1.101.2.10 2005/09/28 06:56:14 rwatson Exp $
   31  */
   32 
   33 #include <sys/param.h>
   34 #include <sys/event.h>
   35 #include <sys/filio.h>
   36 #include <sys/fcntl.h>
   37 #include <sys/file.h>
   38 #include <sys/kernel.h>
   39 #include <sys/lock.h>
   40 #include <sys/mutex.h>
   41 #include <sys/malloc.h>
   42 #include <sys/poll.h>
   43 #include <sys/proc.h> /* XXXKSE */
   44 #include <sys/signalvar.h>
   45 #include <sys/socket.h>
   46 #include <sys/socketvar.h>
   47 #include <sys/sx.h>
   48 #include <sys/systm.h>
   49 #include <sys/un.h>
   50 #include <sys/unistd.h>
   51 #include <sys/vnode.h>
   52 #include <fs/fifofs/fifo.h>
   53 
   54 /*
   55  * This structure is associated with the FIFO vnode and stores
   56  * the state associated with the FIFO.
   57  */
   58 struct fifoinfo {
   59         struct socket   *fi_readsock;
   60         struct socket   *fi_writesock;
   61         long            fi_readers;
   62         long            fi_writers;
   63 };
   64 
   65 static int      fifo_print(struct vop_print_args *);
   66 static int      fifo_lookup(struct vop_lookup_args *);
   67 static int      fifo_open(struct vop_open_args *);
   68 static int      fifo_close(struct vop_close_args *);
   69 static int      fifo_read(struct vop_read_args *);
   70 static int      fifo_write(struct vop_write_args *);
   71 static int      fifo_ioctl(struct vop_ioctl_args *);
   72 static int      fifo_poll(struct vop_poll_args *);
   73 static int      fifo_kqfilter(struct vop_kqfilter_args *);
   74 static int      fifo_pathconf(struct vop_pathconf_args *);
   75 static int      fifo_advlock(struct vop_advlock_args *);
   76 
   77 static void     filt_fifordetach(struct knote *kn);
   78 static int      filt_fiforead(struct knote *kn, long hint);
   79 static void     filt_fifowdetach(struct knote *kn);
   80 static int      filt_fifowrite(struct knote *kn, long hint);
   81 
   82 static struct filterops fiforead_filtops =
   83         { 1, NULL, filt_fifordetach, filt_fiforead };
   84 static struct filterops fifowrite_filtops =
   85         { 1, NULL, filt_fifowdetach, filt_fifowrite };
   86 
   87 vop_t **fifo_vnodeop_p;
   88 static struct vnodeopv_entry_desc fifo_vnodeop_entries[] = {
   89         { &vop_default_desc,            (vop_t *) vop_defaultop },
   90         { &vop_access_desc,             (vop_t *) vop_ebadf },
   91         { &vop_advlock_desc,            (vop_t *) fifo_advlock },
   92         { &vop_close_desc,              (vop_t *) fifo_close },
   93         { &vop_create_desc,             (vop_t *) vop_panic },
   94         { &vop_getattr_desc,            (vop_t *) vop_ebadf },
   95         { &vop_getwritemount_desc,      (vop_t *) vop_stdgetwritemount },
   96         { &vop_ioctl_desc,              (vop_t *) fifo_ioctl },
   97         { &vop_kqfilter_desc,           (vop_t *) fifo_kqfilter },
   98         { &vop_lease_desc,              (vop_t *) vop_null },
   99         { &vop_link_desc,               (vop_t *) vop_panic },
  100         { &vop_lookup_desc,             (vop_t *) fifo_lookup },
  101         { &vop_mkdir_desc,              (vop_t *) vop_panic },
  102         { &vop_mknod_desc,              (vop_t *) vop_panic },
  103         { &vop_open_desc,               (vop_t *) fifo_open },
  104         { &vop_pathconf_desc,           (vop_t *) fifo_pathconf },
  105         { &vop_poll_desc,               (vop_t *) fifo_poll },
  106         { &vop_print_desc,              (vop_t *) fifo_print },
  107         { &vop_read_desc,               (vop_t *) fifo_read },
  108         { &vop_readdir_desc,            (vop_t *) vop_panic },
  109         { &vop_readlink_desc,           (vop_t *) vop_panic },
  110         { &vop_reallocblks_desc,        (vop_t *) vop_panic },
  111         { &vop_reclaim_desc,            (vop_t *) vop_null },
  112         { &vop_remove_desc,             (vop_t *) vop_panic },
  113         { &vop_rename_desc,             (vop_t *) vop_panic },
  114         { &vop_rmdir_desc,              (vop_t *) vop_panic },
  115         { &vop_setattr_desc,            (vop_t *) vop_ebadf },
  116         { &vop_symlink_desc,            (vop_t *) vop_panic },
  117         { &vop_write_desc,              (vop_t *) fifo_write },
  118         { NULL, NULL }
  119 };
  120 static struct vnodeopv_desc fifo_vnodeop_opv_desc =
  121         { &fifo_vnodeop_p, fifo_vnodeop_entries };
  122 
  123 VNODEOP_SET(fifo_vnodeop_opv_desc);
  124 
  125 struct mtx fifo_mtx;
  126 MTX_SYSINIT(fifo, &fifo_mtx, "fifo mutex", MTX_DEF);
  127 
  128 int
  129 fifo_vnoperate(ap)
  130         struct vop_generic_args /* {
  131                 struct vnodeop_desc *a_desc;
  132                 <other random data follows, presumably>
  133         } */ *ap;
  134 {
  135         return (VOCALL(fifo_vnodeop_p, ap->a_desc->vdesc_offset, ap));
  136 }
  137 
  138 /*
  139  * Trivial lookup routine that always fails.
  140  */
  141 /* ARGSUSED */
  142 static int
  143 fifo_lookup(ap)
  144         struct vop_lookup_args /* {
  145                 struct vnode * a_dvp;
  146                 struct vnode ** a_vpp;
  147                 struct componentname * a_cnp;
  148         } */ *ap;
  149 {
  150 
  151         *ap->a_vpp = NULL;
  152         return (ENOTDIR);
  153 }
  154 
  155 /*
  156  * Dispose of fifo resources.
  157  */
  158 static void
  159 fifo_cleanup(struct vnode *vp)
  160 {
  161         struct fifoinfo *fip = vp->v_fifoinfo;
  162 
  163         ASSERT_VOP_LOCKED(vp, "fifo_cleanup");
  164         if (fip->fi_readers == 0 && fip->fi_writers == 0) {
  165                 vp->v_fifoinfo = NULL;
  166                 (void)soclose(fip->fi_readsock);
  167                 (void)soclose(fip->fi_writesock);
  168                 FREE(fip, M_VNODE);
  169         }
  170 }
  171 
  172 /*
  173  * Open called to set up a new instance of a fifo or
  174  * to find an active instance of a fifo.
  175  */
  176 /* ARGSUSED */
  177 static int
  178 fifo_open(ap)
  179         struct vop_open_args /* {
  180                 struct vnode *a_vp;
  181                 int  a_mode;
  182                 struct ucred *a_cred;
  183                 struct thread *a_td;
  184         } */ *ap;
  185 {
  186         struct vnode *vp = ap->a_vp;
  187         struct fifoinfo *fip;
  188         struct thread *td = ap->a_td;
  189         struct ucred *cred = ap->a_cred;
  190         struct socket *rso, *wso;
  191         int error;
  192 
  193         ASSERT_VOP_LOCKED(vp, "fifo_open");
  194         if ((fip = vp->v_fifoinfo) == NULL) {
  195                 MALLOC(fip, struct fifoinfo *, sizeof(*fip), M_VNODE, M_WAITOK);
  196                 error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, cred, td);
  197                 if (error)
  198                         goto fail1;
  199                 fip->fi_readsock = rso;
  200                 error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0, cred, td);
  201                 if (error)
  202                         goto fail2;
  203                 fip->fi_writesock = wso;
  204                 error = soconnect2(wso, rso);
  205                 if (error) {
  206                         (void)soclose(wso);
  207 fail2:
  208                         (void)soclose(rso);
  209 fail1:
  210                         free(fip, M_VNODE);
  211                         return (error);
  212                 }
  213                 fip->fi_readers = fip->fi_writers = 0;
  214                 wso->so_snd.sb_lowat = PIPE_BUF;
  215                 SOCKBUF_LOCK(&rso->so_rcv);
  216                 rso->so_rcv.sb_state |= SBS_CANTRCVMORE;
  217                 SOCKBUF_UNLOCK(&rso->so_rcv);
  218                 KASSERT(vp->v_fifoinfo == NULL,
  219                     ("fifo_open: v_fifoinfo race"));
  220                 vp->v_fifoinfo = fip;
  221         }
  222 
  223         /*
  224          * General access to fi_readers and fi_writers is protected using
  225          * the vnode lock.
  226          *
  227          * Protect the increment of fi_readers and fi_writers and the
  228          * associated calls to wakeup() with the fifo mutex in addition
  229          * to the vnode lock.  This allows the vnode lock to be dropped
  230          * for the msleep() calls below, and using the fifo mutex with
  231          * msleep() prevents the wakeup from being missed.
  232          */
  233         mtx_lock(&fifo_mtx);
  234         if (ap->a_mode & FREAD) {
  235                 fip->fi_readers++;
  236                 if (fip->fi_readers == 1) {
  237                         SOCKBUF_LOCK(&fip->fi_writesock->so_snd);
  238                         fip->fi_writesock->so_snd.sb_state &= ~SBS_CANTSENDMORE;
  239                         SOCKBUF_UNLOCK(&fip->fi_writesock->so_snd);
  240                         if (fip->fi_writers > 0) {
  241                                 wakeup(&fip->fi_writers);
  242                                 sowwakeup(fip->fi_writesock);
  243                         }
  244                 }
  245         }
  246         if (ap->a_mode & FWRITE) {
  247                 if ((ap->a_mode & O_NONBLOCK) && fip->fi_readers == 0) {
  248                         mtx_unlock(&fifo_mtx);
  249                         return (ENXIO);
  250                 }
  251                 fip->fi_writers++;
  252                 if (fip->fi_writers == 1) {
  253                         SOCKBUF_LOCK(&fip->fi_readsock->so_rcv);
  254                         fip->fi_readsock->so_rcv.sb_state &= ~SBS_CANTRCVMORE;
  255                         SOCKBUF_UNLOCK(&fip->fi_readsock->so_rcv);
  256                         if (fip->fi_readers > 0) {
  257                                 wakeup(&fip->fi_readers);
  258                                 sorwakeup(fip->fi_readsock);
  259                         }
  260                 }
  261         }
  262         if ((ap->a_mode & O_NONBLOCK) == 0) {
  263                 if ((ap->a_mode & FREAD) && fip->fi_writers == 0) {
  264                         VOP_UNLOCK(vp, 0, td);
  265                         error = msleep(&fip->fi_readers, &fifo_mtx,
  266                             PDROP | PCATCH | PSOCK, "fifoor", 0);
  267                         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
  268                         if (error) {
  269                                 fip->fi_readers--;
  270                                 if (fip->fi_readers == 0) {
  271                                         socantsendmore(fip->fi_writesock);
  272                                         fifo_cleanup(vp);
  273                                 }
  274                                 return (error);
  275                         }
  276                         mtx_lock(&fifo_mtx);
  277                         /*
  278                          * We must have got woken up because we had a writer.
  279                          * That (and not still having one) is the condition
  280                          * that we must wait for.
  281                          */
  282                 }
  283                 if ((ap->a_mode & FWRITE) && fip->fi_readers == 0) {
  284                         VOP_UNLOCK(vp, 0, td);
  285                         error = msleep(&fip->fi_writers, &fifo_mtx,
  286                             PDROP | PCATCH | PSOCK, "fifoow", 0);
  287                         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
  288                         if (error) {
  289                                 fip->fi_writers--;
  290                                 if (fip->fi_writers == 0) {
  291                                         socantrcvmore(fip->fi_readsock);
  292                                         fifo_cleanup(vp);
  293                                 }
  294                                 return (error);
  295                         }
  296                         /*
  297                          * We must have got woken up because we had
  298                          * a reader.  That (and not still having one)
  299                          * is the condition that we must wait for.
  300                          */
  301                         return (0);
  302                 }
  303         }
  304         mtx_unlock(&fifo_mtx);
  305         return (0);
  306 }
  307 
  308 /*
  309  * Vnode op for read
  310  */
  311 /* ARGSUSED */
  312 static int
  313 fifo_read(ap)
  314         struct vop_read_args /* {
  315                 struct vnode *a_vp;
  316                 struct uio *a_uio;
  317                 int  a_ioflag;
  318                 struct ucred *a_cred;
  319         } */ *ap;
  320 {
  321         struct uio *uio = ap->a_uio;
  322         struct socket *rso = ap->a_vp->v_fifoinfo->fi_readsock;
  323         struct thread *td = uio->uio_td;
  324         int error, flags;
  325 
  326 #ifdef DIAGNOSTIC
  327         if (uio->uio_rw != UIO_READ)
  328                 panic("fifo_read mode");
  329 #endif
  330         if (uio->uio_resid == 0)
  331                 return (0);
  332         VOP_UNLOCK(ap->a_vp, 0, td);
  333         flags = (ap->a_ioflag & IO_NDELAY) ? MSG_NBIO : 0;
  334         error = soreceive(rso, (struct sockaddr **)0, uio, (struct mbuf **)0,
  335             (struct mbuf **)0, &flags);
  336         vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, td);
  337         return (error);
  338 }
  339 
  340 /*
  341  * Vnode op for write
  342  */
  343 /* ARGSUSED */
  344 static int
  345 fifo_write(ap)
  346         struct vop_write_args /* {
  347                 struct vnode *a_vp;
  348                 struct uio *a_uio;
  349                 int  a_ioflag;
  350                 struct ucred *a_cred;
  351         } */ *ap;
  352 {
  353         struct socket *wso = ap->a_vp->v_fifoinfo->fi_writesock;
  354         struct thread *td = ap->a_uio->uio_td;
  355         int error, flags;
  356 
  357 #ifdef DIAGNOSTIC
  358         if (ap->a_uio->uio_rw != UIO_WRITE)
  359                 panic("fifo_write mode");
  360 #endif
  361         VOP_UNLOCK(ap->a_vp, 0, td);
  362         flags = (ap->a_ioflag & IO_NDELAY) ? MSG_NBIO : 0;
  363         error = sosend(wso, (struct sockaddr *)0, ap->a_uio, 0,
  364             (struct mbuf *)0, flags, td);
  365         vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, td);
  366         return (error);
  367 }
  368 
  369 /*
  370  * Device ioctl operation.
  371  */
  372 /* ARGSUSED */
  373 static int
  374 fifo_ioctl(ap)
  375         struct vop_ioctl_args /* {
  376                 struct vnode *a_vp;
  377                 u_long  a_command;
  378                 caddr_t  a_data;
  379                 int  a_fflag;
  380                 struct ucred *a_cred;
  381                 struct thread *a_td;
  382         } */ *ap;
  383 {
  384         struct file filetmp;    /* Local, so need not be locked. */
  385         int error;
  386 
  387         if (ap->a_command == FIONBIO)
  388                 return (0);
  389         if (ap->a_fflag & FREAD) {
  390                 filetmp.f_data = ap->a_vp->v_fifoinfo->fi_readsock;
  391                 filetmp.f_cred = ap->a_cred;
  392                 error = soo_ioctl(&filetmp, ap->a_command, ap->a_data,
  393                     ap->a_td->td_ucred, ap->a_td);
  394                 if (error)
  395                         return (error);
  396         }
  397         if (ap->a_fflag & FWRITE) {
  398                 filetmp.f_data = ap->a_vp->v_fifoinfo->fi_writesock;
  399                 filetmp.f_cred = ap->a_cred;
  400                 error = soo_ioctl(&filetmp, ap->a_command, ap->a_data,
  401                     ap->a_td->td_ucred, ap->a_td);
  402                 if (error)
  403                         return (error);
  404         }
  405         return (0);
  406 }
  407 
  408 /* ARGSUSED */
  409 static int
  410 fifo_kqfilter(ap)
  411         struct vop_kqfilter_args /* {
  412                 struct vnode *a_vp;
  413                 struct knote *a_kn;
  414         } */ *ap;
  415 {
  416         struct fifoinfo *fi = ap->a_vp->v_fifoinfo;
  417         struct socket *so;
  418         struct sockbuf *sb;
  419 
  420         switch (ap->a_kn->kn_filter) {
  421         case EVFILT_READ:
  422                 ap->a_kn->kn_fop = &fiforead_filtops;
  423                 so = fi->fi_readsock;
  424                 sb = &so->so_rcv;
  425                 break;
  426         case EVFILT_WRITE:
  427                 ap->a_kn->kn_fop = &fifowrite_filtops;
  428                 so = fi->fi_writesock;
  429                 sb = &so->so_snd;
  430                 break;
  431         default:
  432                 return (EINVAL);
  433         }
  434 
  435         ap->a_kn->kn_hook = (caddr_t)so;
  436 
  437         SOCKBUF_LOCK(sb);
  438         knlist_add(&sb->sb_sel.si_note, ap->a_kn, 1);
  439         sb->sb_flags |= SB_KNOTE;
  440         SOCKBUF_UNLOCK(sb);
  441 
  442         return (0);
  443 }
  444 
  445 static void
  446 filt_fifordetach(struct knote *kn)
  447 {
  448         struct socket *so = (struct socket *)kn->kn_hook;
  449 
  450         SOCKBUF_LOCK(&so->so_rcv);
  451         knlist_remove(&so->so_rcv.sb_sel.si_note, kn, 1);
  452         if (knlist_empty(&so->so_rcv.sb_sel.si_note))
  453                 so->so_rcv.sb_flags &= ~SB_KNOTE;
  454         SOCKBUF_UNLOCK(&so->so_rcv);
  455 }
  456 
  457 static int
  458 filt_fiforead(struct knote *kn, long hint)
  459 {
  460         struct socket *so = (struct socket *)kn->kn_hook;
  461 
  462         SOCKBUF_LOCK_ASSERT(&so->so_rcv);
  463         kn->kn_data = so->so_rcv.sb_cc;
  464         if (so->so_rcv.sb_state & SBS_CANTRCVMORE) {
  465                 kn->kn_flags |= EV_EOF;
  466                 return (1);
  467         } else {
  468                 kn->kn_flags &= ~EV_EOF;
  469                 return (kn->kn_data > 0);
  470         }
  471 }
  472 
  473 static void
  474 filt_fifowdetach(struct knote *kn)
  475 {
  476         struct socket *so = (struct socket *)kn->kn_hook;
  477 
  478         SOCKBUF_LOCK(&so->so_snd);
  479         knlist_remove(&so->so_snd.sb_sel.si_note, kn, 1);
  480         if (knlist_empty(&so->so_snd.sb_sel.si_note))
  481                 so->so_snd.sb_flags &= ~SB_KNOTE;
  482         SOCKBUF_UNLOCK(&so->so_snd);
  483 }
  484 
  485 static int
  486 filt_fifowrite(struct knote *kn, long hint)
  487 {
  488         struct socket *so = (struct socket *)kn->kn_hook;
  489 
  490         SOCKBUF_LOCK_ASSERT(&so->so_snd);
  491         kn->kn_data = sbspace(&so->so_snd);
  492         if (so->so_snd.sb_state & SBS_CANTSENDMORE) {
  493                 kn->kn_flags |= EV_EOF;
  494                 return (1);
  495         } else {
  496                 kn->kn_flags &= ~EV_EOF;
  497                 return (kn->kn_data >= so->so_snd.sb_lowat);
  498         }
  499 }
  500 
  501 /* ARGSUSED */
  502 static int
  503 fifo_poll(ap)
  504         struct vop_poll_args /* {
  505                 struct vnode *a_vp;
  506                 int  a_events;
  507                 struct ucred *a_cred;
  508                 struct thread *a_td;
  509         } */ *ap;
  510 {
  511         struct file filetmp;
  512         int events, revents = 0;
  513 
  514         events = ap->a_events &
  515             (POLLIN | POLLINIGNEOF | POLLPRI | POLLRDNORM | POLLRDBAND);
  516         if (events) {
  517                 /*
  518                  * If POLLIN or POLLRDNORM is requested and POLLINIGNEOF is
  519                  * not, then convert the first two to the last one.  This
  520                  * tells the socket poll function to ignore EOF so that we
  521                  * block if there is no writer (and no data).  Callers can
  522                  * set POLLINIGNEOF to get non-blocking behavior.
  523                  */
  524                 if (events & (POLLIN | POLLRDNORM) &&
  525                     !(events & POLLINIGNEOF)) {
  526                         events &= ~(POLLIN | POLLRDNORM);
  527                         events |= POLLINIGNEOF;
  528                 }
  529 
  530                 filetmp.f_data = ap->a_vp->v_fifoinfo->fi_readsock;
  531                 filetmp.f_cred = ap->a_cred;
  532                 revents |= soo_poll(&filetmp, events, ap->a_td->td_ucred,
  533                     ap->a_td);
  534 
  535                 /* Reverse the above conversion. */
  536                 if ((revents & POLLINIGNEOF) &&
  537                     !(ap->a_events & POLLINIGNEOF)) {
  538                         revents |= (ap->a_events & (POLLIN | POLLRDNORM));
  539                         revents &= ~POLLINIGNEOF;
  540                 }
  541         }
  542         events = ap->a_events & (POLLOUT | POLLWRNORM | POLLWRBAND);
  543         if (events) {
  544                 filetmp.f_data = ap->a_vp->v_fifoinfo->fi_writesock;
  545                 filetmp.f_cred = ap->a_cred;
  546                 revents |= soo_poll(&filetmp, events, ap->a_td->td_ucred,
  547                     ap->a_td);
  548         }
  549         return (revents);
  550 }
  551 
  552 /*
  553  * Device close routine
  554  */
  555 /* ARGSUSED */
  556 static int
  557 fifo_close(ap)
  558         struct vop_close_args /* {
  559                 struct vnode *a_vp;
  560                 int  a_fflag;
  561                 struct ucred *a_cred;
  562                 struct thread *a_td;
  563         } */ *ap;
  564 {
  565         struct vnode *vp = ap->a_vp;
  566         struct thread *td = ap->a_td;
  567         struct fifoinfo *fip = vp->v_fifoinfo;
  568 
  569         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
  570 
  571         ASSERT_VOP_LOCKED(vp, "fifo_close");
  572         if (ap->a_fflag & FREAD) {
  573                 fip->fi_readers--;
  574                 if (fip->fi_readers == 0)
  575                         socantsendmore(fip->fi_writesock);
  576         }
  577         if (ap->a_fflag & FWRITE) {
  578                 fip->fi_writers--;
  579                 if (fip->fi_writers == 0)
  580                         socantrcvmore(fip->fi_readsock);
  581         }
  582         fifo_cleanup(vp);
  583         VOP_UNLOCK(vp, 0, td);
  584         return (0);
  585 }
  586 
  587 /*
  588  * Print out internal contents of a fifo vnode.
  589  */
  590 int
  591 fifo_printinfo(vp)
  592         struct vnode *vp;
  593 {
  594         register struct fifoinfo *fip = vp->v_fifoinfo;
  595 
  596         printf(", fifo with %ld readers and %ld writers",
  597                 fip->fi_readers, fip->fi_writers);
  598         return (0);
  599 }
  600 
  601 /*
  602  * Print out the contents of a fifo vnode.
  603  */
  604 static int
  605 fifo_print(ap)
  606         struct vop_print_args /* {
  607                 struct vnode *a_vp;
  608         } */ *ap;
  609 {
  610         fifo_printinfo(ap->a_vp);
  611         printf("\n");
  612         return (0);
  613 }
  614 
  615 /*
  616  * Return POSIX pathconf information applicable to fifo's.
  617  */
  618 static int
  619 fifo_pathconf(ap)
  620         struct vop_pathconf_args /* {
  621                 struct vnode *a_vp;
  622                 int a_name;
  623                 int *a_retval;
  624         } */ *ap;
  625 {
  626 
  627         switch (ap->a_name) {
  628         case _PC_LINK_MAX:
  629                 *ap->a_retval = LINK_MAX;
  630                 return (0);
  631         case _PC_PIPE_BUF:
  632                 *ap->a_retval = PIPE_BUF;
  633                 return (0);
  634         case _PC_CHOWN_RESTRICTED:
  635                 *ap->a_retval = 1;
  636                 return (0);
  637         default:
  638                 return (EINVAL);
  639         }
  640         /* NOTREACHED */
  641 }
  642 
  643 /*
  644  * Fifo advisory byte-level locks.
  645  */
  646 /* ARGSUSED */
  647 static int
  648 fifo_advlock(ap)
  649         struct vop_advlock_args /* {
  650                 struct vnode *a_vp;
  651                 caddr_t  a_id;
  652                 int  a_op;
  653                 struct flock *a_fl;
  654                 int  a_flags;
  655         } */ *ap;
  656 {
  657 
  658         return (ap->a_flags & F_FLOCK ? EOPNOTSUPP : EINVAL);
  659 }

Cache object: 8172287fc5ec81ff34eaefc423874e09


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.