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

Cache object: 00b9dc5cf62bcedd7e21cbdbc4a46e89


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