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.
    4  * Copyright (c) 2005 Robert N. M. Watson
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 4. Neither the name of the University nor the names of its contributors
   16  *    may be used to endorse or promote products derived from this software
   17  *    without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  *
   31  *      @(#)fifo_vnops.c        8.10 (Berkeley) 5/27/95
   32  * $FreeBSD: releng/6.0/sys/fs/fifofs/fifo_vnops.c 150934 2005-10-04 15:33:06Z rwatson $
   33  */
   34 
   35 #include <sys/param.h>
   36 #include <sys/event.h>
   37 #include <sys/file.h>
   38 #include <sys/filedesc.h>
   39 #include <sys/filio.h>
   40 #include <sys/fcntl.h>
   41 #include <sys/kernel.h>
   42 #include <sys/lock.h>
   43 #include <sys/mutex.h>
   44 #include <sys/malloc.h>
   45 #include <sys/poll.h>
   46 #include <sys/proc.h> /* XXXKSE */
   47 #include <sys/signalvar.h>
   48 #include <sys/socket.h>
   49 #include <sys/socketvar.h>
   50 #include <sys/sx.h>
   51 #include <sys/systm.h>
   52 #include <sys/un.h>
   53 #include <sys/unistd.h>
   54 #include <sys/vnode.h>
   55 #include <fs/fifofs/fifo.h>
   56 
   57 static fo_rdwr_t        fifo_read_f;
   58 static fo_rdwr_t        fifo_write_f;
   59 static fo_ioctl_t       fifo_ioctl_f;
   60 static fo_poll_t        fifo_poll_f;
   61 static fo_kqfilter_t    fifo_kqfilter_f;
   62 static fo_stat_t        fifo_stat_f;
   63 static fo_close_t       fifo_close_f;
   64 
   65 struct fileops fifo_ops_f = {
   66         .fo_read =      fifo_read_f,
   67         .fo_write =     fifo_write_f,
   68         .fo_ioctl =     fifo_ioctl_f,
   69         .fo_poll =      fifo_poll_f,
   70         .fo_kqfilter =  fifo_kqfilter_f,
   71         .fo_stat =      fifo_stat_f,
   72         .fo_close =     fifo_close_f,
   73         .fo_flags =     DFLAG_PASSABLE
   74 };
   75 
   76 /*
   77  * This structure is associated with the FIFO vnode and stores
   78  * the state associated with the FIFO.
   79  */
   80 struct fifoinfo {
   81         struct socket   *fi_readsock;
   82         struct socket   *fi_writesock;
   83         long            fi_readers;
   84         long            fi_writers;
   85 };
   86 
   87 static vop_print_t      fifo_print;
   88 static vop_open_t       fifo_open;
   89 static vop_close_t      fifo_close;
   90 static vop_ioctl_t      fifo_ioctl;
   91 static vop_kqfilter_t   fifo_kqfilter;
   92 static vop_pathconf_t   fifo_pathconf;
   93 static vop_advlock_t    fifo_advlock;
   94 
   95 static void     filt_fifordetach(struct knote *kn);
   96 static int      filt_fiforead(struct knote *kn, long hint);
   97 static void     filt_fifowdetach(struct knote *kn);
   98 static int      filt_fifowrite(struct knote *kn, long hint);
   99 static void     filt_fifodetach_notsup(struct knote *kn);
  100 static int      filt_fifo_notsup(struct knote *kn, long hint);
  101 
  102 static struct filterops fiforead_filtops =
  103         { 1, NULL, filt_fifordetach, filt_fiforead };
  104 static struct filterops fifowrite_filtops =
  105         { 1, NULL, filt_fifowdetach, filt_fifowrite };
  106 static struct filterops fifo_notsup_filtops =
  107         { 1, NULL, filt_fifodetach_notsup, filt_fifo_notsup };
  108 
  109 struct vop_vector fifo_specops = {
  110         .vop_default =          &default_vnodeops,
  111 
  112         .vop_access =           VOP_EBADF,
  113         .vop_advlock =          fifo_advlock,
  114         .vop_close =            fifo_close,
  115         .vop_create =           VOP_PANIC,
  116         .vop_getattr =          VOP_EBADF,
  117         .vop_ioctl =            fifo_ioctl,
  118         .vop_kqfilter =         fifo_kqfilter,
  119         .vop_lease =            VOP_NULL,
  120         .vop_link =             VOP_PANIC,
  121         .vop_mkdir =            VOP_PANIC,
  122         .vop_mknod =            VOP_PANIC,
  123         .vop_open =             fifo_open,
  124         .vop_pathconf =         fifo_pathconf,
  125         .vop_print =            fifo_print,
  126         .vop_read =             VOP_PANIC,
  127         .vop_readdir =          VOP_PANIC,
  128         .vop_readlink =         VOP_PANIC,
  129         .vop_reallocblks =      VOP_PANIC,
  130         .vop_reclaim =          VOP_NULL,
  131         .vop_remove =           VOP_PANIC,
  132         .vop_rename =           VOP_PANIC,
  133         .vop_rmdir =            VOP_PANIC,
  134         .vop_setattr =          VOP_EBADF,
  135         .vop_symlink =          VOP_PANIC,
  136         .vop_write =            VOP_PANIC,
  137 };
  138 
  139 struct mtx fifo_mtx;
  140 MTX_SYSINIT(fifo, &fifo_mtx, "fifo mutex", MTX_DEF);
  141 
  142 /*
  143  * Dispose of fifo resources.
  144  */
  145 static void
  146 fifo_cleanup(struct vnode *vp)
  147 {
  148         struct fifoinfo *fip = vp->v_fifoinfo;
  149 
  150         ASSERT_VOP_LOCKED(vp, "fifo_cleanup");
  151         if (fip->fi_readers == 0 && fip->fi_writers == 0) {
  152                 vp->v_fifoinfo = NULL;
  153                 (void)soclose(fip->fi_readsock);
  154                 (void)soclose(fip->fi_writesock);
  155                 FREE(fip, M_VNODE);
  156         }
  157 }
  158 
  159 /*
  160  * Open called to set up a new instance of a fifo or
  161  * to find an active instance of a fifo.
  162  */
  163 /* ARGSUSED */
  164 static int
  165 fifo_open(ap)
  166         struct vop_open_args /* {
  167                 struct vnode *a_vp;
  168                 int  a_mode;
  169                 struct ucred *a_cred;
  170                 struct thread *a_td;
  171         } */ *ap;
  172 {
  173         struct vnode *vp = ap->a_vp;
  174         struct fifoinfo *fip;
  175         struct thread *td = ap->a_td;
  176         struct ucred *cred = ap->a_cred;
  177         struct socket *rso, *wso;
  178         struct file *fp;
  179         int error;
  180 
  181         ASSERT_VOP_LOCKED(vp, "fifo_open");
  182         if ((fip = vp->v_fifoinfo) == NULL) {
  183                 MALLOC(fip, struct fifoinfo *, sizeof(*fip), M_VNODE, M_WAITOK);
  184                 error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, cred, td);
  185                 if (error)
  186                         goto fail1;
  187                 fip->fi_readsock = rso;
  188                 error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0, cred, td);
  189                 if (error)
  190                         goto fail2;
  191                 fip->fi_writesock = wso;
  192                 error = soconnect2(wso, rso);
  193                 if (error) {
  194                         (void)soclose(wso);
  195 fail2:
  196                         (void)soclose(rso);
  197 fail1:
  198                         free(fip, M_VNODE);
  199                         return (error);
  200                 }
  201                 fip->fi_readers = fip->fi_writers = 0;
  202                 wso->so_snd.sb_lowat = PIPE_BUF;
  203                 SOCKBUF_LOCK(&rso->so_rcv);
  204                 rso->so_rcv.sb_state |= SBS_CANTRCVMORE;
  205                 SOCKBUF_UNLOCK(&rso->so_rcv);
  206                 KASSERT(vp->v_fifoinfo == NULL,
  207                     ("fifo_open: v_fifoinfo race"));
  208                 vp->v_fifoinfo = fip;
  209         }
  210 
  211         /*
  212          * General access to fi_readers and fi_writers is protected using
  213          * the vnode lock.
  214          *
  215          * Protect the increment of fi_readers and fi_writers and the
  216          * associated calls to wakeup() with the fifo mutex in addition
  217          * to the vnode lock.  This allows the vnode lock to be dropped
  218          * for the msleep() calls below, and using the fifo mutex with
  219          * msleep() prevents the wakeup from being missed.
  220          */
  221         mtx_lock(&fifo_mtx);
  222         if (ap->a_mode & FREAD) {
  223                 fip->fi_readers++;
  224                 if (fip->fi_readers == 1) {
  225                         SOCKBUF_LOCK(&fip->fi_writesock->so_snd);
  226                         fip->fi_writesock->so_snd.sb_state &= ~SBS_CANTSENDMORE;
  227                         SOCKBUF_UNLOCK(&fip->fi_writesock->so_snd);
  228                         if (fip->fi_writers > 0) {
  229                                 wakeup(&fip->fi_writers);
  230                                 sowwakeup(fip->fi_writesock);
  231                         }
  232                 }
  233         }
  234         if (ap->a_mode & FWRITE) {
  235                 if ((ap->a_mode & O_NONBLOCK) && fip->fi_readers == 0) {
  236                         mtx_unlock(&fifo_mtx);
  237                         return (ENXIO);
  238                 }
  239                 fip->fi_writers++;
  240                 if (fip->fi_writers == 1) {
  241                         SOCKBUF_LOCK(&fip->fi_readsock->so_rcv);
  242                         fip->fi_readsock->so_rcv.sb_state &= ~SBS_CANTRCVMORE;
  243                         SOCKBUF_UNLOCK(&fip->fi_readsock->so_rcv);
  244                         if (fip->fi_readers > 0) {
  245                                 wakeup(&fip->fi_readers);
  246                                 sorwakeup(fip->fi_readsock);
  247                         }
  248                 }
  249         }
  250         if ((ap->a_mode & O_NONBLOCK) == 0) {
  251                 if ((ap->a_mode & FREAD) && fip->fi_writers == 0) {
  252                         VOP_UNLOCK(vp, 0, td);
  253                         error = msleep(&fip->fi_readers, &fifo_mtx,
  254                             PDROP | PCATCH | PSOCK, "fifoor", 0);
  255                         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
  256                         if (error) {
  257                                 fip->fi_readers--;
  258                                 if (fip->fi_readers == 0) {
  259                                         socantsendmore(fip->fi_writesock);
  260                                         fifo_cleanup(vp);
  261                                 }
  262                                 return (error);
  263                         }
  264                         mtx_lock(&fifo_mtx);
  265                         /*
  266                          * We must have got woken up because we had a writer.
  267                          * That (and not still having one) is the condition
  268                          * that we must wait for.
  269                          */
  270                 }
  271                 if ((ap->a_mode & FWRITE) && fip->fi_readers == 0) {
  272                         VOP_UNLOCK(vp, 0, td);
  273                         error = msleep(&fip->fi_writers, &fifo_mtx,
  274                             PDROP | PCATCH | PSOCK, "fifoow", 0);
  275                         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
  276                         if (error) {
  277                                 fip->fi_writers--;
  278                                 if (fip->fi_writers == 0) {
  279                                         socantrcvmore(fip->fi_readsock);
  280                                         fifo_cleanup(vp);
  281                                 }
  282                                 return (error);
  283                         }
  284                         /*
  285                          * We must have got woken up because we had
  286                          * a reader.  That (and not still having one)
  287                          * is the condition that we must wait for.
  288                          */
  289                         mtx_lock(&fifo_mtx);
  290                 }
  291         }
  292         mtx_unlock(&fifo_mtx);
  293         KASSERT(ap->a_fdidx >= 0, ("can't fifo/vnode bypass %d", ap->a_fdidx));
  294         fp = ap->a_td->td_proc->p_fd->fd_ofiles[ap->a_fdidx];
  295         KASSERT(fp->f_ops == &badfileops, ("not badfileops in fifo_open"));
  296         fp->f_ops = &fifo_ops_f;
  297         fp->f_data = fip;
  298         return (0);
  299 }
  300 
  301 /*
  302  * Now unused vnode ioctl routine.
  303  */
  304 /* ARGSUSED */
  305 static int
  306 fifo_ioctl(ap)
  307         struct vop_ioctl_args /* {
  308                 struct vnode *a_vp;
  309                 u_long  a_command;
  310                 caddr_t  a_data;
  311                 int  a_fflag;
  312                 struct ucred *a_cred;
  313                 struct thread *a_td;
  314         } */ *ap;
  315 {
  316 
  317         printf("WARNING: fifo_ioctl called unexpectedly\n");
  318         return (ENOTTY);
  319 }
  320 
  321 /*
  322  * Now unused vnode kqfilter routine.
  323  */
  324 /* ARGSUSED */
  325 static int
  326 fifo_kqfilter(ap)
  327         struct vop_kqfilter_args /* {
  328                 struct vnode *a_vp;
  329                 struct knote *a_kn;
  330         } */ *ap;
  331 {
  332 
  333         printf("WARNING: fifo_kqfilter called unexpectedly\n");
  334         return (EINVAL);
  335 }
  336 
  337 static void
  338 filt_fifordetach(struct knote *kn)
  339 {
  340         struct socket *so = (struct socket *)kn->kn_hook;
  341 
  342         SOCKBUF_LOCK(&so->so_rcv);
  343         knlist_remove(&so->so_rcv.sb_sel.si_note, kn, 1);
  344         if (knlist_empty(&so->so_rcv.sb_sel.si_note))
  345                 so->so_rcv.sb_flags &= ~SB_KNOTE;
  346         SOCKBUF_UNLOCK(&so->so_rcv);
  347 }
  348 
  349 static int
  350 filt_fiforead(struct knote *kn, long hint)
  351 {
  352         struct socket *so = (struct socket *)kn->kn_hook;
  353 
  354         SOCKBUF_LOCK_ASSERT(&so->so_rcv);
  355         kn->kn_data = so->so_rcv.sb_cc;
  356         if (so->so_rcv.sb_state & SBS_CANTRCVMORE) {
  357                 kn->kn_flags |= EV_EOF;
  358                 return (1);
  359         } else {
  360                 kn->kn_flags &= ~EV_EOF;
  361                 return (kn->kn_data > 0);
  362         }
  363 }
  364 
  365 static void
  366 filt_fifowdetach(struct knote *kn)
  367 {
  368         struct socket *so = (struct socket *)kn->kn_hook;
  369 
  370         SOCKBUF_LOCK(&so->so_snd);
  371         knlist_remove(&so->so_snd.sb_sel.si_note, kn, 1);
  372         if (knlist_empty(&so->so_snd.sb_sel.si_note))
  373                 so->so_snd.sb_flags &= ~SB_KNOTE;
  374         SOCKBUF_UNLOCK(&so->so_snd);
  375 }
  376 
  377 static int
  378 filt_fifowrite(struct knote *kn, long hint)
  379 {
  380         struct socket *so = (struct socket *)kn->kn_hook;
  381 
  382         SOCKBUF_LOCK_ASSERT(&so->so_snd);
  383         kn->kn_data = sbspace(&so->so_snd);
  384         if (so->so_snd.sb_state & SBS_CANTSENDMORE) {
  385                 kn->kn_flags |= EV_EOF;
  386                 return (1);
  387         } else {
  388                 kn->kn_flags &= ~EV_EOF;
  389                 return (kn->kn_data >= so->so_snd.sb_lowat);
  390         }
  391 }
  392 
  393 static void
  394 filt_fifodetach_notsup(struct knote *kn)
  395 {
  396 
  397 }
  398 
  399 static int
  400 filt_fifo_notsup(struct knote *kn, long hint)
  401 {
  402 
  403         return (0);
  404 }
  405 
  406 /*
  407  * Device close routine
  408  */
  409 /* ARGSUSED */
  410 static int
  411 fifo_close(ap)
  412         struct vop_close_args /* {
  413                 struct vnode *a_vp;
  414                 int  a_fflag;
  415                 struct ucred *a_cred;
  416                 struct thread *a_td;
  417         } */ *ap;
  418 {
  419         struct vnode *vp = ap->a_vp;
  420         struct fifoinfo *fip = vp->v_fifoinfo;
  421 
  422         ASSERT_VOP_LOCKED(vp, "fifo_close");
  423         KASSERT(fip != NULL, ("fifo_close: no v_fifoinfo"));
  424         if (ap->a_fflag & FREAD) {
  425                 fip->fi_readers--;
  426                 if (fip->fi_readers == 0)
  427                         socantsendmore(fip->fi_writesock);
  428         }
  429         if (ap->a_fflag & FWRITE) {
  430                 fip->fi_writers--;
  431                 if (fip->fi_writers == 0)
  432                         socantrcvmore(fip->fi_readsock);
  433         }
  434         fifo_cleanup(vp);
  435         return (0);
  436 }
  437 
  438 /*
  439  * Print out internal contents of a fifo vnode.
  440  */
  441 int
  442 fifo_printinfo(vp)
  443         struct vnode *vp;
  444 {
  445         register struct fifoinfo *fip = vp->v_fifoinfo;
  446 
  447         printf(", fifo with %ld readers and %ld writers",
  448                 fip->fi_readers, fip->fi_writers);
  449         return (0);
  450 }
  451 
  452 /*
  453  * Print out the contents of a fifo vnode.
  454  */
  455 static int
  456 fifo_print(ap)
  457         struct vop_print_args /* {
  458                 struct vnode *a_vp;
  459         } */ *ap;
  460 {
  461         fifo_printinfo(ap->a_vp);
  462         printf("\n");
  463         return (0);
  464 }
  465 
  466 /*
  467  * Return POSIX pathconf information applicable to fifo's.
  468  */
  469 static int
  470 fifo_pathconf(ap)
  471         struct vop_pathconf_args /* {
  472                 struct vnode *a_vp;
  473                 int a_name;
  474                 int *a_retval;
  475         } */ *ap;
  476 {
  477 
  478         switch (ap->a_name) {
  479         case _PC_LINK_MAX:
  480                 *ap->a_retval = LINK_MAX;
  481                 return (0);
  482         case _PC_PIPE_BUF:
  483                 *ap->a_retval = PIPE_BUF;
  484                 return (0);
  485         case _PC_CHOWN_RESTRICTED:
  486                 *ap->a_retval = 1;
  487                 return (0);
  488         default:
  489                 return (EINVAL);
  490         }
  491         /* NOTREACHED */
  492 }
  493 
  494 /*
  495  * Fifo advisory byte-level locks.
  496  */
  497 /* ARGSUSED */
  498 static int
  499 fifo_advlock(ap)
  500         struct vop_advlock_args /* {
  501                 struct vnode *a_vp;
  502                 caddr_t  a_id;
  503                 int  a_op;
  504                 struct flock *a_fl;
  505                 int  a_flags;
  506         } */ *ap;
  507 {
  508 
  509         return (ap->a_flags & F_FLOCK ? EOPNOTSUPP : EINVAL);
  510 }
  511 
  512 static int
  513 fifo_close_f(struct file *fp, struct thread *td)
  514 {
  515 
  516         return (vnops.fo_close(fp, td));
  517 }
  518 
  519 /*
  520  * The implementation of ioctl() for named fifos is complicated by the fact
  521  * that we permit O_RDWR fifo file descriptors, meaning that the actions of
  522  * ioctls may have to be applied to both the underlying sockets rather than
  523  * just one.  The original implementation simply forward the ioctl to one
  524  * or both sockets based on fp->f_flag.  We now consider each ioctl
  525  * separately, as the composition effect requires careful ordering.
  526  *
  527  * We do not blindly pass all ioctls through to the socket in order to avoid
  528  * providing unnecessary ioctls that might be improperly depended on by
  529  * applications (such as socket-specific, routing, and interface ioctls).
  530  *
  531  * Unlike sys_pipe.c, fifos do not implement the deprecated TIOCSPGRP and
  532  * TIOCGPGRP ioctls.  Earlier implementations of fifos did forward SIOCSPGRP
  533  * and SIOCGPGRP ioctls, so we might need to re-add those here.
  534  */
  535 static int
  536 fifo_ioctl_f(struct file *fp, u_long com, void *data, struct ucred *cred,
  537     struct thread *td)
  538 {
  539         struct fifoinfo *fi;
  540         struct file filetmp;    /* Local, so need not be locked. */
  541         int error;
  542 
  543         error = ENOTTY;
  544         fi = fp->f_data;
  545 
  546         switch (com) {
  547         case FIONBIO:
  548                 /*
  549                  * Non-blocking I/O is implemented at the fifo layer using
  550                  * MSG_NBIO, so does not need to be forwarded down the stack.
  551                  */
  552                 return (0);
  553 
  554         case FIOASYNC:
  555         case FIOSETOWN:
  556         case FIOGETOWN:
  557                 /*
  558                  * These socket ioctls don't have any ordering requirements,
  559                  * so are called in an arbitrary order, and only on the
  560                  * sockets indicated by the file descriptor rights.
  561                  *
  562                  * XXXRW: If O_RDWR and the read socket accepts an ioctl but
  563                  * the write socket doesn't, the socketpair is left in an
  564                  * inconsistent state.
  565                  */
  566                 if (fp->f_flag & FREAD) {
  567                         filetmp.f_data = fi->fi_readsock;
  568                         filetmp.f_cred = cred;
  569                         error = soo_ioctl(&filetmp, com, data, cred, td);
  570                         if (error)
  571                                 return (error);
  572                 }
  573                 if (fp->f_flag & FWRITE) {
  574                         filetmp.f_data = fi->fi_writesock;
  575                         filetmp.f_cred = cred;
  576                         error = soo_ioctl(&filetmp, com, data, cred, td);
  577                 }
  578                 return (error);
  579 
  580         case FIONREAD:
  581                 /*
  582                  * FIONREAD will return 0 for non-readable descriptors, and
  583                  * the results of FIONREAD on the read socket for readable
  584                  * descriptors.
  585                  */
  586                 if (!(fp->f_flag & FREAD)) {
  587                         *(int *)data = 0;
  588                         return (0);
  589                 }
  590                 filetmp.f_data = fi->fi_readsock;
  591                 filetmp.f_cred = cred;
  592                 return (soo_ioctl(&filetmp, com, data, cred, td));
  593 
  594         default:
  595                 return (ENOTTY);
  596         }
  597 }
  598 
  599 /*
  600  * Because fifos are now a file descriptor layer object, EVFILT_VNODE is not
  601  * implemented.  Likely, fifo_kqfilter() should be removed, and
  602  * fifo_kqfilter_f() should know how to forward the request to the underling
  603  * vnode using f_vnode in the file descriptor here.
  604  */
  605 static int
  606 fifo_kqfilter_f(struct file *fp, struct knote *kn)
  607 {
  608         struct fifoinfo *fi;
  609         struct socket *so;
  610         struct sockbuf *sb;
  611 
  612         fi = fp->f_data;
  613 
  614         /*
  615          * If a filter is requested that is not supported by this file
  616          * descriptor, don't return an error, but also don't ever generate an
  617          * event.
  618          */
  619         if ((kn->kn_filter == EVFILT_READ) && !(fp->f_flag & FREAD)) {
  620                 kn->kn_fop = &fifo_notsup_filtops;
  621                 return (0);
  622         }
  623 
  624         if ((kn->kn_filter == EVFILT_WRITE) && !(fp->f_flag & FWRITE)) {
  625                 kn->kn_fop = &fifo_notsup_filtops;
  626                 return (0);
  627         }
  628 
  629         switch (kn->kn_filter) {
  630         case EVFILT_READ:
  631                 kn->kn_fop = &fiforead_filtops;
  632                 so = fi->fi_readsock;
  633                 sb = &so->so_rcv;
  634                 break;
  635         case EVFILT_WRITE:
  636                 kn->kn_fop = &fifowrite_filtops;
  637                 so = fi->fi_writesock;
  638                 sb = &so->so_snd;
  639                 break;
  640         default:
  641                 return (EINVAL);
  642         }
  643 
  644         kn->kn_hook = (caddr_t)so;
  645 
  646         SOCKBUF_LOCK(sb);
  647         knlist_add(&sb->sb_sel.si_note, kn, 1);
  648         sb->sb_flags |= SB_KNOTE;
  649         SOCKBUF_UNLOCK(sb);
  650 
  651         return (0);
  652 }
  653 
  654 static int
  655 fifo_poll_f(struct file *fp, int events, struct ucred *cred, struct thread *td)
  656 {
  657         struct fifoinfo *fip;
  658         struct file filetmp;
  659         int levents, revents = 0;
  660 
  661         fip = fp->f_data;
  662         levents = events &
  663             (POLLIN | POLLINIGNEOF | POLLPRI | POLLRDNORM | POLLRDBAND);
  664         if ((fp->f_flag & FREAD) && levents) {
  665                 /*
  666                  * If POLLIN or POLLRDNORM is requested and POLLINIGNEOF is
  667                  * not, then convert the first two to the last one.  This
  668                  * tells the socket poll function to ignore EOF so that we
  669                  * block if there is no writer (and no data).  Callers can
  670                  * set POLLINIGNEOF to get non-blocking behavior.
  671                  */
  672                 if (levents & (POLLIN | POLLRDNORM) &&
  673                     !(levents & POLLINIGNEOF)) {
  674                         levents &= ~(POLLIN | POLLRDNORM);
  675                         levents |= POLLINIGNEOF;
  676                 }
  677 
  678                 filetmp.f_data = fip->fi_readsock;
  679                 filetmp.f_cred = cred;
  680                 revents |= soo_poll(&filetmp, levents, cred, td);
  681 
  682                 /* Reverse the above conversion. */
  683                 if ((revents & POLLINIGNEOF) && !(events & POLLINIGNEOF)) {
  684                         revents |= (events & (POLLIN | POLLRDNORM));
  685                         revents &= ~POLLINIGNEOF;
  686                 }
  687         }
  688         levents = events & (POLLOUT | POLLWRNORM | POLLWRBAND);
  689         if ((fp->f_flag & FWRITE) && levents) {
  690                 filetmp.f_data = fip->fi_writesock;
  691                 filetmp.f_cred = cred;
  692                 revents |= soo_poll(&filetmp, levents, cred, td);
  693         }
  694         return (revents);
  695 }
  696 
  697 static int
  698 fifo_read_f(struct file *fp, struct uio *uio, struct ucred *cred, int flags, struct thread *td)
  699 {
  700         struct fifoinfo *fip;
  701         int error, sflags;
  702 
  703         fip = fp->f_data;
  704         KASSERT(uio->uio_rw == UIO_READ,("fifo_read mode"));
  705         if (uio->uio_resid == 0)
  706                 return (0);
  707         sflags = (fp->f_flag & FNONBLOCK) ? MSG_NBIO : 0;
  708         mtx_lock(&Giant);
  709         error = soreceive(fip->fi_readsock, NULL, uio, NULL, NULL, &sflags);
  710         mtx_unlock(&Giant);
  711         return (error);
  712 }
  713 
  714 static int
  715 fifo_stat_f(struct file *fp, struct stat *sb, struct ucred *cred, struct thread *td)
  716 {
  717 
  718         return (vnops.fo_stat(fp, sb, cred, td));
  719 }
  720 
  721 static int
  722 fifo_write_f(struct file *fp, struct uio *uio, struct ucred *cred, int flags, struct thread *td)
  723 {
  724         struct fifoinfo *fip;
  725         int error, sflags;
  726 
  727         fip = fp->f_data;
  728         KASSERT(uio->uio_rw == UIO_WRITE,("fifo_write mode"));
  729         sflags = (fp->f_flag & FNONBLOCK) ? MSG_NBIO : 0;
  730         mtx_lock(&Giant);
  731         error = sosend(fip->fi_writesock, NULL, uio, 0, NULL, sflags, td);
  732         mtx_unlock(&Giant);
  733         return (error);
  734 }

Cache object: d7ee0563c80d5069a43a03b555edbb41


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