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

Cache object: 0e4e827aab50109bbee229d0d1d3ca41


[ 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.