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.4/sys/fs/fifofs/fifo_vnops.c 172428 2007-10-03 21:06:05Z jhb $
   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                 int a_fdidx;
  172         } */ *ap;
  173 {
  174         struct vnode *vp = ap->a_vp;
  175         struct fifoinfo *fip;
  176         struct thread *td = ap->a_td;
  177         struct ucred *cred = ap->a_cred;
  178         struct socket *rso, *wso;
  179         struct file *fp;
  180         int error;
  181 
  182         ASSERT_VOP_ELOCKED(vp, "fifo_open");
  183         if (ap->a_fdidx < 0)
  184                 return (EINVAL);
  185         if ((fip = vp->v_fifoinfo) == NULL) {
  186                 MALLOC(fip, struct fifoinfo *, sizeof(*fip), M_VNODE, M_WAITOK);
  187                 error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, cred, td);
  188                 if (error)
  189                         goto fail1;
  190                 fip->fi_readsock = rso;
  191                 error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0, cred, td);
  192                 if (error)
  193                         goto fail2;
  194                 fip->fi_writesock = wso;
  195                 error = soconnect2(wso, rso);
  196                 if (error) {
  197                         (void)soclose(wso);
  198 fail2:
  199                         (void)soclose(rso);
  200 fail1:
  201                         free(fip, M_VNODE);
  202                         return (error);
  203                 }
  204                 fip->fi_readers = fip->fi_writers = 0;
  205                 wso->so_snd.sb_lowat = PIPE_BUF;
  206                 SOCKBUF_LOCK(&rso->so_rcv);
  207                 rso->so_rcv.sb_state |= SBS_CANTRCVMORE;
  208                 SOCKBUF_UNLOCK(&rso->so_rcv);
  209                 KASSERT(vp->v_fifoinfo == NULL,
  210                     ("fifo_open: v_fifoinfo race"));
  211                 vp->v_fifoinfo = fip;
  212         }
  213 
  214         /*
  215          * General access to fi_readers and fi_writers is protected using
  216          * the vnode lock.
  217          *
  218          * Protect the increment of fi_readers and fi_writers and the
  219          * associated calls to wakeup() with the fifo mutex in addition
  220          * to the vnode lock.  This allows the vnode lock to be dropped
  221          * for the msleep() calls below, and using the fifo mutex with
  222          * msleep() prevents the wakeup from being missed.
  223          */
  224         mtx_lock(&fifo_mtx);
  225         if (ap->a_mode & FREAD) {
  226                 fip->fi_readers++;
  227                 if (fip->fi_readers == 1) {
  228                         SOCKBUF_LOCK(&fip->fi_writesock->so_snd);
  229                         fip->fi_writesock->so_snd.sb_state &= ~SBS_CANTSENDMORE;
  230                         SOCKBUF_UNLOCK(&fip->fi_writesock->so_snd);
  231                         if (fip->fi_writers > 0) {
  232                                 wakeup(&fip->fi_writers);
  233                                 sowwakeup(fip->fi_writesock);
  234                         }
  235                 }
  236         }
  237         if (ap->a_mode & FWRITE) {
  238                 if ((ap->a_mode & O_NONBLOCK) && fip->fi_readers == 0) {
  239                         mtx_unlock(&fifo_mtx);
  240                         return (ENXIO);
  241                 }
  242                 fip->fi_writers++;
  243                 if (fip->fi_writers == 1) {
  244                         SOCKBUF_LOCK(&fip->fi_readsock->so_rcv);
  245                         fip->fi_readsock->so_rcv.sb_state &= ~SBS_CANTRCVMORE;
  246                         SOCKBUF_UNLOCK(&fip->fi_readsock->so_rcv);
  247                         if (fip->fi_readers > 0) {
  248                                 wakeup(&fip->fi_readers);
  249                                 sorwakeup(fip->fi_readsock);
  250                         }
  251                 }
  252         }
  253         if ((ap->a_mode & O_NONBLOCK) == 0) {
  254                 if ((ap->a_mode & FREAD) && fip->fi_writers == 0) {
  255                         VOP_UNLOCK(vp, 0, td);
  256                         error = msleep(&fip->fi_readers, &fifo_mtx,
  257                             PDROP | PCATCH | PSOCK, "fifoor", 0);
  258                         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
  259                         if (error) {
  260                                 fip->fi_readers--;
  261                                 if (fip->fi_readers == 0) {
  262                                         socantsendmore(fip->fi_writesock);
  263                                         fifo_cleanup(vp);
  264                                 }
  265                                 return (error);
  266                         }
  267                         mtx_lock(&fifo_mtx);
  268                         /*
  269                          * We must have got woken up because we had a writer.
  270                          * That (and not still having one) is the condition
  271                          * that we must wait for.
  272                          */
  273                 }
  274                 if ((ap->a_mode & FWRITE) && fip->fi_readers == 0) {
  275                         VOP_UNLOCK(vp, 0, td);
  276                         error = msleep(&fip->fi_writers, &fifo_mtx,
  277                             PDROP | PCATCH | PSOCK, "fifoow", 0);
  278                         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
  279                         if (error) {
  280                                 fip->fi_writers--;
  281                                 if (fip->fi_writers == 0) {
  282                                         socantrcvmore(fip->fi_readsock);
  283                                         fifo_cleanup(vp);
  284                                 }
  285                                 return (error);
  286                         }
  287                         /*
  288                          * We must have got woken up because we had
  289                          * a reader.  That (and not still having one)
  290                          * is the condition that we must wait for.
  291                          */
  292                         mtx_lock(&fifo_mtx);
  293                 }
  294         }
  295         mtx_unlock(&fifo_mtx);
  296         KASSERT(ap->a_fdidx >= 0, ("can't fifo/vnode bypass %d", ap->a_fdidx));
  297         fp = ap->a_td->td_proc->p_fd->fd_ofiles[ap->a_fdidx];
  298         KASSERT(fp->f_ops == &badfileops, ("not badfileops in fifo_open"));
  299         fp->f_ops = &fifo_ops_f;
  300         fp->f_data = fip;
  301         return (0);
  302 }
  303 
  304 /*
  305  * Now unused vnode ioctl routine.
  306  */
  307 /* ARGSUSED */
  308 static int
  309 fifo_ioctl(ap)
  310         struct vop_ioctl_args /* {
  311                 struct vnode *a_vp;
  312                 u_long  a_command;
  313                 caddr_t  a_data;
  314                 int  a_fflag;
  315                 struct ucred *a_cred;
  316                 struct thread *a_td;
  317         } */ *ap;
  318 {
  319 
  320         printf("WARNING: fifo_ioctl called unexpectedly\n");
  321         return (ENOTTY);
  322 }
  323 
  324 /*
  325  * Now unused vnode kqfilter routine.
  326  */
  327 /* ARGSUSED */
  328 static int
  329 fifo_kqfilter(ap)
  330         struct vop_kqfilter_args /* {
  331                 struct vnode *a_vp;
  332                 struct knote *a_kn;
  333         } */ *ap;
  334 {
  335 
  336         printf("WARNING: fifo_kqfilter called unexpectedly\n");
  337         return (EINVAL);
  338 }
  339 
  340 static void
  341 filt_fifordetach(struct knote *kn)
  342 {
  343         struct socket *so = (struct socket *)kn->kn_hook;
  344 
  345         SOCKBUF_LOCK(&so->so_rcv);
  346         knlist_remove(&so->so_rcv.sb_sel.si_note, kn, 1);
  347         if (knlist_empty(&so->so_rcv.sb_sel.si_note))
  348                 so->so_rcv.sb_flags &= ~SB_KNOTE;
  349         SOCKBUF_UNLOCK(&so->so_rcv);
  350 }
  351 
  352 static int
  353 filt_fiforead(struct knote *kn, long hint)
  354 {
  355         struct socket *so = (struct socket *)kn->kn_hook;
  356 
  357         SOCKBUF_LOCK_ASSERT(&so->so_rcv);
  358         kn->kn_data = so->so_rcv.sb_cc;
  359         if (so->so_rcv.sb_state & SBS_CANTRCVMORE) {
  360                 kn->kn_flags |= EV_EOF;
  361                 return (1);
  362         } else {
  363                 kn->kn_flags &= ~EV_EOF;
  364                 return (kn->kn_data > 0);
  365         }
  366 }
  367 
  368 static void
  369 filt_fifowdetach(struct knote *kn)
  370 {
  371         struct socket *so = (struct socket *)kn->kn_hook;
  372 
  373         SOCKBUF_LOCK(&so->so_snd);
  374         knlist_remove(&so->so_snd.sb_sel.si_note, kn, 1);
  375         if (knlist_empty(&so->so_snd.sb_sel.si_note))
  376                 so->so_snd.sb_flags &= ~SB_KNOTE;
  377         SOCKBUF_UNLOCK(&so->so_snd);
  378 }
  379 
  380 static int
  381 filt_fifowrite(struct knote *kn, long hint)
  382 {
  383         struct socket *so = (struct socket *)kn->kn_hook;
  384 
  385         SOCKBUF_LOCK_ASSERT(&so->so_snd);
  386         kn->kn_data = sbspace(&so->so_snd);
  387         if (so->so_snd.sb_state & SBS_CANTSENDMORE) {
  388                 kn->kn_flags |= EV_EOF;
  389                 return (1);
  390         } else {
  391                 kn->kn_flags &= ~EV_EOF;
  392                 return (kn->kn_data >= so->so_snd.sb_lowat);
  393         }
  394 }
  395 
  396 static void
  397 filt_fifodetach_notsup(struct knote *kn)
  398 {
  399 
  400 }
  401 
  402 static int
  403 filt_fifo_notsup(struct knote *kn, long hint)
  404 {
  405 
  406         return (0);
  407 }
  408 
  409 /*
  410  * Device close routine
  411  */
  412 /* ARGSUSED */
  413 static int
  414 fifo_close(ap)
  415         struct vop_close_args /* {
  416                 struct vnode *a_vp;
  417                 int  a_fflag;
  418                 struct ucred *a_cred;
  419                 struct thread *a_td;
  420         } */ *ap;
  421 {
  422         struct vnode *vp = ap->a_vp;
  423         struct fifoinfo *fip = vp->v_fifoinfo;
  424 
  425         ASSERT_VOP_LOCKED(vp, "fifo_close");
  426         KASSERT(fip != NULL, ("fifo_close: no v_fifoinfo"));
  427         if (ap->a_fflag & FREAD) {
  428                 fip->fi_readers--;
  429                 if (fip->fi_readers == 0)
  430                         socantsendmore(fip->fi_writesock);
  431         }
  432         if (ap->a_fflag & FWRITE) {
  433                 fip->fi_writers--;
  434                 if (fip->fi_writers == 0)
  435                         socantrcvmore(fip->fi_readsock);
  436         }
  437         fifo_cleanup(vp);
  438         return (0);
  439 }
  440 
  441 /*
  442  * Print out internal contents of a fifo vnode.
  443  */
  444 int
  445 fifo_printinfo(vp)
  446         struct vnode *vp;
  447 {
  448         register struct fifoinfo *fip = vp->v_fifoinfo;
  449 
  450         printf(", fifo with %ld readers and %ld writers",
  451                 fip->fi_readers, fip->fi_writers);
  452         return (0);
  453 }
  454 
  455 /*
  456  * Print out the contents of a fifo vnode.
  457  */
  458 static int
  459 fifo_print(ap)
  460         struct vop_print_args /* {
  461                 struct vnode *a_vp;
  462         } */ *ap;
  463 {
  464         fifo_printinfo(ap->a_vp);
  465         printf("\n");
  466         return (0);
  467 }
  468 
  469 /*
  470  * Return POSIX pathconf information applicable to fifo's.
  471  */
  472 static int
  473 fifo_pathconf(ap)
  474         struct vop_pathconf_args /* {
  475                 struct vnode *a_vp;
  476                 int a_name;
  477                 int *a_retval;
  478         } */ *ap;
  479 {
  480 
  481         switch (ap->a_name) {
  482         case _PC_LINK_MAX:
  483                 *ap->a_retval = LINK_MAX;
  484                 return (0);
  485         case _PC_PIPE_BUF:
  486                 *ap->a_retval = PIPE_BUF;
  487                 return (0);
  488         case _PC_CHOWN_RESTRICTED:
  489                 *ap->a_retval = 1;
  490                 return (0);
  491         default:
  492                 return (EINVAL);
  493         }
  494         /* NOTREACHED */
  495 }
  496 
  497 /*
  498  * Fifo advisory byte-level locks.
  499  */
  500 /* ARGSUSED */
  501 static int
  502 fifo_advlock(ap)
  503         struct vop_advlock_args /* {
  504                 struct vnode *a_vp;
  505                 caddr_t  a_id;
  506                 int  a_op;
  507                 struct flock *a_fl;
  508                 int  a_flags;
  509         } */ *ap;
  510 {
  511 
  512         return (ap->a_flags & F_FLOCK ? EOPNOTSUPP : EINVAL);
  513 }
  514 
  515 static int
  516 fifo_close_f(struct file *fp, struct thread *td)
  517 {
  518 
  519         return (vnops.fo_close(fp, td));
  520 }
  521 
  522 /*
  523  * The implementation of ioctl() for named fifos is complicated by the fact
  524  * that we permit O_RDWR fifo file descriptors, meaning that the actions of
  525  * ioctls may have to be applied to both the underlying sockets rather than
  526  * just one.  The original implementation simply forward the ioctl to one
  527  * or both sockets based on fp->f_flag.  We now consider each ioctl
  528  * separately, as the composition effect requires careful ordering.
  529  *
  530  * We do not blindly pass all ioctls through to the socket in order to avoid
  531  * providing unnecessary ioctls that might be improperly depended on by
  532  * applications (such as socket-specific, routing, and interface ioctls).
  533  *
  534  * Unlike sys_pipe.c, fifos do not implement the deprecated TIOCSPGRP and
  535  * TIOCGPGRP ioctls.  Earlier implementations of fifos did forward SIOCSPGRP
  536  * and SIOCGPGRP ioctls, so we might need to re-add those here.
  537  */
  538 static int
  539 fifo_ioctl_f(struct file *fp, u_long com, void *data, struct ucred *cred,
  540     struct thread *td)
  541 {
  542         struct fifoinfo *fi;
  543         struct file filetmp;    /* Local, so need not be locked. */
  544         int error;
  545 
  546         error = ENOTTY;
  547         fi = fp->f_data;
  548 
  549         switch (com) {
  550         case FIONBIO:
  551                 /*
  552                  * Non-blocking I/O is implemented at the fifo layer using
  553                  * MSG_NBIO, so does not need to be forwarded down the stack.
  554                  */
  555                 return (0);
  556 
  557         case FIOASYNC:
  558         case FIOSETOWN:
  559         case FIOGETOWN:
  560                 /*
  561                  * These socket ioctls don't have any ordering requirements,
  562                  * so are called in an arbitrary order, and only on the
  563                  * sockets indicated by the file descriptor rights.
  564                  *
  565                  * XXXRW: If O_RDWR and the read socket accepts an ioctl but
  566                  * the write socket doesn't, the socketpair is left in an
  567                  * inconsistent state.
  568                  */
  569                 if (fp->f_flag & FREAD) {
  570                         filetmp.f_data = fi->fi_readsock;
  571                         filetmp.f_cred = cred;
  572                         error = soo_ioctl(&filetmp, com, data, cred, td);
  573                         if (error)
  574                                 return (error);
  575                 }
  576                 if (fp->f_flag & FWRITE) {
  577                         filetmp.f_data = fi->fi_writesock;
  578                         filetmp.f_cred = cred;
  579                         error = soo_ioctl(&filetmp, com, data, cred, td);
  580                 }
  581                 return (error);
  582 
  583         case FIONREAD:
  584                 /*
  585                  * FIONREAD will return 0 for non-readable descriptors, and
  586                  * the results of FIONREAD on the read socket for readable
  587                  * descriptors.
  588                  */
  589                 if (!(fp->f_flag & FREAD)) {
  590                         *(int *)data = 0;
  591                         return (0);
  592                 }
  593                 filetmp.f_data = fi->fi_readsock;
  594                 filetmp.f_cred = cred;
  595                 return (soo_ioctl(&filetmp, com, data, cred, td));
  596 
  597         default:
  598                 return (ENOTTY);
  599         }
  600 }
  601 
  602 /*
  603  * Because fifos are now a file descriptor layer object, EVFILT_VNODE is not
  604  * implemented.  Likely, fifo_kqfilter() should be removed, and
  605  * fifo_kqfilter_f() should know how to forward the request to the underling
  606  * vnode using f_vnode in the file descriptor here.
  607  */
  608 static int
  609 fifo_kqfilter_f(struct file *fp, struct knote *kn)
  610 {
  611         struct fifoinfo *fi;
  612         struct socket *so;
  613         struct sockbuf *sb;
  614 
  615         fi = fp->f_data;
  616 
  617         /*
  618          * If a filter is requested that is not supported by this file
  619          * descriptor, don't return an error, but also don't ever generate an
  620          * event.
  621          */
  622         if ((kn->kn_filter == EVFILT_READ) && !(fp->f_flag & FREAD)) {
  623                 kn->kn_fop = &fifo_notsup_filtops;
  624                 return (0);
  625         }
  626 
  627         if ((kn->kn_filter == EVFILT_WRITE) && !(fp->f_flag & FWRITE)) {
  628                 kn->kn_fop = &fifo_notsup_filtops;
  629                 return (0);
  630         }
  631 
  632         switch (kn->kn_filter) {
  633         case EVFILT_READ:
  634                 kn->kn_fop = &fiforead_filtops;
  635                 so = fi->fi_readsock;
  636                 sb = &so->so_rcv;
  637                 break;
  638         case EVFILT_WRITE:
  639                 kn->kn_fop = &fifowrite_filtops;
  640                 so = fi->fi_writesock;
  641                 sb = &so->so_snd;
  642                 break;
  643         default:
  644                 return (EINVAL);
  645         }
  646 
  647         kn->kn_hook = (caddr_t)so;
  648 
  649         SOCKBUF_LOCK(sb);
  650         knlist_add(&sb->sb_sel.si_note, kn, 1);
  651         sb->sb_flags |= SB_KNOTE;
  652         SOCKBUF_UNLOCK(sb);
  653 
  654         return (0);
  655 }
  656 
  657 static int
  658 fifo_poll_f(struct file *fp, int events, struct ucred *cred, struct thread *td)
  659 {
  660         struct fifoinfo *fip;
  661         struct file filetmp;
  662         int levents, revents = 0;
  663 
  664         fip = fp->f_data;
  665         levents = events &
  666             (POLLIN | POLLINIGNEOF | POLLPRI | POLLRDNORM | POLLRDBAND);
  667         if ((fp->f_flag & FREAD) && levents) {
  668                 /*
  669                  * If POLLIN or POLLRDNORM is requested and POLLINIGNEOF is
  670                  * not, then convert the first two to the last one.  This
  671                  * tells the socket poll function to ignore EOF so that we
  672                  * block if there is no writer (and no data).  Callers can
  673                  * set POLLINIGNEOF to get non-blocking behavior.
  674                  */
  675                 if (levents & (POLLIN | POLLRDNORM) &&
  676                     !(levents & POLLINIGNEOF)) {
  677                         levents &= ~(POLLIN | POLLRDNORM);
  678                         levents |= POLLINIGNEOF;
  679                 }
  680 
  681                 filetmp.f_data = fip->fi_readsock;
  682                 filetmp.f_cred = cred;
  683                 revents |= soo_poll(&filetmp, levents, cred, td);
  684 
  685                 /* Reverse the above conversion. */
  686                 if ((revents & POLLINIGNEOF) && !(events & POLLINIGNEOF)) {
  687                         revents |= (events & (POLLIN | POLLRDNORM));
  688                         revents &= ~POLLINIGNEOF;
  689                 }
  690         }
  691         levents = events & (POLLOUT | POLLWRNORM | POLLWRBAND);
  692         if ((fp->f_flag & FWRITE) && levents) {
  693                 filetmp.f_data = fip->fi_writesock;
  694                 filetmp.f_cred = cred;
  695                 revents |= soo_poll(&filetmp, levents, cred, td);
  696         }
  697         return (revents);
  698 }
  699 
  700 static int
  701 fifo_read_f(struct file *fp, struct uio *uio, struct ucred *cred, int flags, struct thread *td)
  702 {
  703         struct fifoinfo *fip;
  704         int error, sflags;
  705 
  706         fip = fp->f_data;
  707         KASSERT(uio->uio_rw == UIO_READ,("fifo_read mode"));
  708         if (uio->uio_resid == 0)
  709                 return (0);
  710         sflags = (fp->f_flag & FNONBLOCK) ? MSG_NBIO : 0;
  711         mtx_lock(&Giant);
  712         error = soreceive(fip->fi_readsock, NULL, uio, NULL, NULL, &sflags);
  713         mtx_unlock(&Giant);
  714         return (error);
  715 }
  716 
  717 static int
  718 fifo_stat_f(struct file *fp, struct stat *sb, struct ucred *cred, struct thread *td)
  719 {
  720 
  721         return (vnops.fo_stat(fp, sb, cred, td));
  722 }
  723 
  724 static int
  725 fifo_write_f(struct file *fp, struct uio *uio, struct ucred *cred, int flags, struct thread *td)
  726 {
  727         struct fifoinfo *fip;
  728         int error, sflags;
  729 
  730         fip = fp->f_data;
  731         KASSERT(uio->uio_rw == UIO_WRITE,("fifo_write mode"));
  732         sflags = (fp->f_flag & FNONBLOCK) ? MSG_NBIO : 0;
  733         mtx_lock(&Giant);
  734         error = sosend(fip->fi_writesock, NULL, uio, 0, NULL, sflags, td);
  735         mtx_unlock(&Giant);
  736         return (error);
  737 }

Cache object: 53a9ce1dbf1aa33447e2850237524073


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