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: releng/5.4/sys/fs/fifofs/fifo_vnops.c 141090 2005-01-31 23:27:04Z imp $
   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         if ((fip = vp->v_fifoinfo) == NULL) {
  194                 MALLOC(fip, struct fifoinfo *, sizeof(*fip), M_VNODE, M_WAITOK);
  195                 error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, cred, td);
  196                 if (error)
  197                         goto fail1;
  198                 fip->fi_readsock = rso;
  199                 error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0, cred, td);
  200                 if (error)
  201                         goto fail2;
  202                 fip->fi_writesock = wso;
  203                 error = uipc_connect2(wso, rso);
  204                 if (error) {
  205                         (void)soclose(wso);
  206 fail2:
  207                         (void)soclose(rso);
  208 fail1:
  209                         free(fip, M_VNODE);
  210                         return (error);
  211                 }
  212                 fip->fi_readers = fip->fi_writers = 0;
  213                 wso->so_snd.sb_lowat = PIPE_BUF;
  214                 SOCKBUF_LOCK(&rso->so_rcv);
  215                 rso->so_rcv.sb_state |= SBS_CANTRCVMORE;
  216                 SOCKBUF_UNLOCK(&rso->so_rcv);
  217                 vp->v_fifoinfo = fip;
  218         }
  219 
  220         /*
  221          * General access to fi_readers and fi_writers is protected using
  222          * the vnode lock.
  223          *
  224          * Protect the increment of fi_readers and fi_writers and the
  225          * associated calls to wakeup() with the fifo mutex in addition
  226          * to the vnode lock.  This allows the vnode lock to be dropped
  227          * for the msleep() calls below, and using the fifo mutex with
  228          * msleep() prevents the wakeup from being missed.
  229          */
  230         mtx_lock(&fifo_mtx);
  231         if (ap->a_mode & FREAD) {
  232                 fip->fi_readers++;
  233                 if (fip->fi_readers == 1) {
  234                         SOCKBUF_LOCK(&fip->fi_writesock->so_snd);
  235                         fip->fi_writesock->so_snd.sb_state &= ~SBS_CANTSENDMORE;
  236                         SOCKBUF_UNLOCK(&fip->fi_writesock->so_snd);
  237                         if (fip->fi_writers > 0) {
  238                                 wakeup(&fip->fi_writers);
  239                                 sowwakeup(fip->fi_writesock);
  240                         }
  241                 }
  242         }
  243         if (ap->a_mode & FWRITE) {
  244                 if ((ap->a_mode & O_NONBLOCK) && fip->fi_readers == 0) {
  245                         mtx_unlock(&fifo_mtx);
  246                         return (ENXIO);
  247                 }
  248                 fip->fi_writers++;
  249                 if (fip->fi_writers == 1) {
  250                         SOCKBUF_LOCK(&fip->fi_writesock->so_rcv);
  251                         fip->fi_readsock->so_rcv.sb_state &= ~SBS_CANTRCVMORE;
  252                         SOCKBUF_UNLOCK(&fip->fi_writesock->so_rcv);
  253                         if (fip->fi_readers > 0) {
  254                                 wakeup(&fip->fi_readers);
  255                                 sorwakeup(fip->fi_writesock);
  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, &fifo_mtx,
  263                             PDROP | PCATCH | PSOCK, "fifoor", 0);
  264                         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
  265                         if (error) {
  266                                 fip->fi_readers--;
  267                                 if (fip->fi_readers == 0) {
  268                                         socantsendmore(fip->fi_writesock);
  269                                         fifo_cleanup(vp);
  270                                 }
  271                                 return (error);
  272                         }
  273                         mtx_lock(&fifo_mtx);
  274                         /*
  275                          * We must have got woken up because we had a writer.
  276                          * That (and not still having one) is the condition
  277                          * that we must wait for.
  278                          */
  279                 }
  280                 if ((ap->a_mode & FWRITE) && fip->fi_readers == 0) {
  281                         VOP_UNLOCK(vp, 0, td);
  282                         error = msleep(&fip->fi_writers, &fifo_mtx,
  283                             PDROP | PCATCH | PSOCK, "fifoow", 0);
  284                         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
  285                         if (error) {
  286                                 fip->fi_writers--;
  287                                 if (fip->fi_writers == 0) {
  288                                         socantrcvmore(fip->fi_readsock);
  289                                         fifo_cleanup(vp);
  290                                 }
  291                                 return (error);
  292                         }
  293                         /*
  294                          * We must have got woken up because we had
  295                          * a reader.  That (and not still having one)
  296                          * is the condition that we must wait for.
  297                          */
  298                         return (0);
  299                 }
  300         }
  301         mtx_unlock(&fifo_mtx);
  302         return (0);
  303 }
  304 
  305 /*
  306  * Vnode op for read
  307  */
  308 /* ARGSUSED */
  309 static int
  310 fifo_read(ap)
  311         struct vop_read_args /* {
  312                 struct vnode *a_vp;
  313                 struct uio *a_uio;
  314                 int  a_ioflag;
  315                 struct ucred *a_cred;
  316         } */ *ap;
  317 {
  318         struct uio *uio = ap->a_uio;
  319         struct socket *rso = ap->a_vp->v_fifoinfo->fi_readsock;
  320         struct thread *td = uio->uio_td;
  321         int error, flags;
  322 
  323 #ifdef DIAGNOSTIC
  324         if (uio->uio_rw != UIO_READ)
  325                 panic("fifo_read mode");
  326 #endif
  327         if (uio->uio_resid == 0)
  328                 return (0);
  329         VOP_UNLOCK(ap->a_vp, 0, td);
  330         flags = (ap->a_ioflag & IO_NDELAY) ? MSG_NBIO : 0;
  331         error = soreceive(rso, (struct sockaddr **)0, uio, (struct mbuf **)0,
  332             (struct mbuf **)0, &flags);
  333         vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, td);
  334         return (error);
  335 }
  336 
  337 /*
  338  * Vnode op for write
  339  */
  340 /* ARGSUSED */
  341 static int
  342 fifo_write(ap)
  343         struct vop_write_args /* {
  344                 struct vnode *a_vp;
  345                 struct uio *a_uio;
  346                 int  a_ioflag;
  347                 struct ucred *a_cred;
  348         } */ *ap;
  349 {
  350         struct socket *wso = ap->a_vp->v_fifoinfo->fi_writesock;
  351         struct thread *td = ap->a_uio->uio_td;
  352         int error, flags;
  353 
  354 #ifdef DIAGNOSTIC
  355         if (ap->a_uio->uio_rw != UIO_WRITE)
  356                 panic("fifo_write mode");
  357 #endif
  358         VOP_UNLOCK(ap->a_vp, 0, td);
  359         flags = (ap->a_ioflag & IO_NDELAY) ? MSG_NBIO : 0;
  360         error = sosend(wso, (struct sockaddr *)0, ap->a_uio, 0,
  361             (struct mbuf *)0, flags, td);
  362         vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, td);
  363         return (error);
  364 }
  365 
  366 /*
  367  * Device ioctl operation.
  368  */
  369 /* ARGSUSED */
  370 static int
  371 fifo_ioctl(ap)
  372         struct vop_ioctl_args /* {
  373                 struct vnode *a_vp;
  374                 u_long  a_command;
  375                 caddr_t  a_data;
  376                 int  a_fflag;
  377                 struct ucred *a_cred;
  378                 struct thread *a_td;
  379         } */ *ap;
  380 {
  381         struct file filetmp;    /* Local, so need not be locked. */
  382         int error;
  383 
  384         if (ap->a_command == FIONBIO)
  385                 return (0);
  386         if (ap->a_fflag & FREAD) {
  387                 filetmp.f_data = ap->a_vp->v_fifoinfo->fi_readsock;
  388                 filetmp.f_cred = ap->a_cred;
  389                 error = soo_ioctl(&filetmp, ap->a_command, ap->a_data,
  390                     ap->a_td->td_ucred, ap->a_td);
  391                 if (error)
  392                         return (error);
  393         }
  394         if (ap->a_fflag & FWRITE) {
  395                 filetmp.f_data = ap->a_vp->v_fifoinfo->fi_writesock;
  396                 filetmp.f_cred = ap->a_cred;
  397                 error = soo_ioctl(&filetmp, ap->a_command, ap->a_data,
  398                     ap->a_td->td_ucred, ap->a_td);
  399                 if (error)
  400                         return (error);
  401         }
  402         return (0);
  403 }
  404 
  405 /* ARGSUSED */
  406 static int
  407 fifo_kqfilter(ap)
  408         struct vop_kqfilter_args /* {
  409                 struct vnode *a_vp;
  410                 struct knote *a_kn;
  411         } */ *ap;
  412 {
  413         struct fifoinfo *fi = ap->a_vp->v_fifoinfo;
  414         struct socket *so;
  415         struct sockbuf *sb;
  416 
  417         switch (ap->a_kn->kn_filter) {
  418         case EVFILT_READ:
  419                 ap->a_kn->kn_fop = &fiforead_filtops;
  420                 so = fi->fi_readsock;
  421                 sb = &so->so_rcv;
  422                 break;
  423         case EVFILT_WRITE:
  424                 ap->a_kn->kn_fop = &fifowrite_filtops;
  425                 so = fi->fi_writesock;
  426                 sb = &so->so_snd;
  427                 break;
  428         default:
  429                 return (1);
  430         }
  431 
  432         ap->a_kn->kn_hook = (caddr_t)so;
  433 
  434         SOCKBUF_LOCK(sb);
  435         knlist_add(&sb->sb_sel.si_note, ap->a_kn, 1);
  436         sb->sb_flags |= SB_KNOTE;
  437         SOCKBUF_UNLOCK(sb);
  438 
  439         return (0);
  440 }
  441 
  442 static void
  443 filt_fifordetach(struct knote *kn)
  444 {
  445         struct socket *so = (struct socket *)kn->kn_hook;
  446 
  447         SOCKBUF_LOCK(&so->so_rcv);
  448         knlist_remove(&so->so_rcv.sb_sel.si_note, kn, 1);
  449         if (knlist_empty(&so->so_rcv.sb_sel.si_note))
  450                 so->so_rcv.sb_flags &= ~SB_KNOTE;
  451         SOCKBUF_UNLOCK(&so->so_rcv);
  452 }
  453 
  454 static int
  455 filt_fiforead(struct knote *kn, long hint)
  456 {
  457         struct socket *so = (struct socket *)kn->kn_hook;
  458         int need_lock, result;
  459 
  460         need_lock = !SOCKBUF_OWNED(&so->so_rcv);
  461         if (need_lock)
  462                 SOCKBUF_LOCK(&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                 result = 1;
  467         } else {
  468                 kn->kn_flags &= ~EV_EOF;
  469                 result = (kn->kn_data > 0);
  470         }
  471         if (need_lock)
  472                 SOCKBUF_UNLOCK(&so->so_rcv);
  473         return (result);
  474 }
  475 
  476 static void
  477 filt_fifowdetach(struct knote *kn)
  478 {
  479         struct socket *so = (struct socket *)kn->kn_hook;
  480 
  481         SOCKBUF_LOCK(&so->so_snd);
  482         knlist_remove(&so->so_snd.sb_sel.si_note, kn, 1);
  483         if (knlist_empty(&so->so_snd.sb_sel.si_note))
  484                 so->so_snd.sb_flags &= ~SB_KNOTE;
  485         SOCKBUF_UNLOCK(&so->so_snd);
  486 }
  487 
  488 static int
  489 filt_fifowrite(struct knote *kn, long hint)
  490 {
  491         struct socket *so = (struct socket *)kn->kn_hook;
  492         int need_lock, result;
  493 
  494         need_lock = !SOCKBUF_OWNED(&so->so_snd);
  495         if (need_lock)
  496                 SOCKBUF_LOCK(&so->so_snd);
  497         kn->kn_data = sbspace(&so->so_snd);
  498         if (so->so_snd.sb_state & SBS_CANTSENDMORE) {
  499                 kn->kn_flags |= EV_EOF;
  500                 result = 1;
  501         } else {
  502                 kn->kn_flags &= ~EV_EOF;
  503                 result = (kn->kn_data >= so->so_snd.sb_lowat);
  504         }
  505         if (need_lock)
  506                 SOCKBUF_UNLOCK(&so->so_snd);
  507         return (result);
  508 }
  509 
  510 /* ARGSUSED */
  511 static int
  512 fifo_poll(ap)
  513         struct vop_poll_args /* {
  514                 struct vnode *a_vp;
  515                 int  a_events;
  516                 struct ucred *a_cred;
  517                 struct thread *a_td;
  518         } */ *ap;
  519 {
  520         struct file filetmp;
  521         int events, revents = 0;
  522 
  523         events = ap->a_events &
  524             (POLLIN | POLLINIGNEOF | POLLPRI | POLLRDNORM | POLLRDBAND);
  525         if (events) {
  526                 /*
  527                  * If POLLIN or POLLRDNORM is requested and POLLINIGNEOF is
  528                  * not, then convert the first two to the last one.  This
  529                  * tells the socket poll function to ignore EOF so that we
  530                  * block if there is no writer (and no data).  Callers can
  531                  * set POLLINIGNEOF to get non-blocking behavior.
  532                  */
  533                 if (events & (POLLIN | POLLRDNORM) &&
  534                     !(events & POLLINIGNEOF)) {
  535                         events &= ~(POLLIN | POLLRDNORM);
  536                         events |= POLLINIGNEOF;
  537                 }
  538 
  539                 filetmp.f_data = ap->a_vp->v_fifoinfo->fi_readsock;
  540                 filetmp.f_cred = ap->a_cred;
  541                 if (filetmp.f_data)
  542                         revents |= soo_poll(&filetmp, events,
  543                             ap->a_td->td_ucred, ap->a_td);
  544 
  545                 /* Reverse the above conversion. */
  546                 if ((revents & POLLINIGNEOF) &&
  547                     !(ap->a_events & POLLINIGNEOF)) {
  548                         revents |= (ap->a_events & (POLLIN | POLLRDNORM));
  549                         revents &= ~POLLINIGNEOF;
  550                 }
  551         }
  552         events = ap->a_events & (POLLOUT | POLLWRNORM | POLLWRBAND);
  553         if (events) {
  554                 filetmp.f_data = ap->a_vp->v_fifoinfo->fi_writesock;
  555                 filetmp.f_cred = ap->a_cred;
  556                 if (filetmp.f_data) {
  557                         revents |= soo_poll(&filetmp, events,
  558                             ap->a_td->td_ucred, ap->a_td);
  559                 }
  560         }
  561         return (revents);
  562 }
  563 
  564 /*
  565  * Device close routine
  566  */
  567 /* ARGSUSED */
  568 static int
  569 fifo_close(ap)
  570         struct vop_close_args /* {
  571                 struct vnode *a_vp;
  572                 int  a_fflag;
  573                 struct ucred *a_cred;
  574                 struct thread *a_td;
  575         } */ *ap;
  576 {
  577         struct vnode *vp = ap->a_vp;
  578         struct thread *td = ap->a_td;
  579         struct fifoinfo *fip = vp->v_fifoinfo;
  580 
  581         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
  582 
  583         if (ap->a_fflag & FREAD) {
  584                 fip->fi_readers--;
  585                 if (fip->fi_readers == 0)
  586                         socantsendmore(fip->fi_writesock);
  587         }
  588         if (ap->a_fflag & FWRITE) {
  589                 fip->fi_writers--;
  590                 if (fip->fi_writers == 0)
  591                         socantrcvmore(fip->fi_readsock);
  592         }
  593         fifo_cleanup(vp);
  594         VOP_UNLOCK(vp, 0, td);
  595         return (0);
  596 }
  597 
  598 /*
  599  * Print out internal contents of a fifo vnode.
  600  */
  601 int
  602 fifo_printinfo(vp)
  603         struct vnode *vp;
  604 {
  605         register struct fifoinfo *fip = vp->v_fifoinfo;
  606 
  607         printf(", fifo with %ld readers and %ld writers",
  608                 fip->fi_readers, fip->fi_writers);
  609         return (0);
  610 }
  611 
  612 /*
  613  * Print out the contents of a fifo vnode.
  614  */
  615 static int
  616 fifo_print(ap)
  617         struct vop_print_args /* {
  618                 struct vnode *a_vp;
  619         } */ *ap;
  620 {
  621         fifo_printinfo(ap->a_vp);
  622         printf("\n");
  623         return (0);
  624 }
  625 
  626 /*
  627  * Return POSIX pathconf information applicable to fifo's.
  628  */
  629 static int
  630 fifo_pathconf(ap)
  631         struct vop_pathconf_args /* {
  632                 struct vnode *a_vp;
  633                 int a_name;
  634                 int *a_retval;
  635         } */ *ap;
  636 {
  637 
  638         switch (ap->a_name) {
  639         case _PC_LINK_MAX:
  640                 *ap->a_retval = LINK_MAX;
  641                 return (0);
  642         case _PC_PIPE_BUF:
  643                 *ap->a_retval = PIPE_BUF;
  644                 return (0);
  645         case _PC_CHOWN_RESTRICTED:
  646                 *ap->a_retval = 1;
  647                 return (0);
  648         default:
  649                 return (EINVAL);
  650         }
  651         /* NOTREACHED */
  652 }
  653 
  654 /*
  655  * Fifo advisory byte-level locks.
  656  */
  657 /* ARGSUSED */
  658 static int
  659 fifo_advlock(ap)
  660         struct vop_advlock_args /* {
  661                 struct vnode *a_vp;
  662                 caddr_t  a_id;
  663                 int  a_op;
  664                 struct flock *a_fl;
  665                 int  a_flags;
  666         } */ *ap;
  667 {
  668 
  669         return (ap->a_flags & F_FLOCK ? EOPNOTSUPP : EINVAL);
  670 }

Cache object: 21798b75e93eb14685144df42d89aa8a


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