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/fifo.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  *  linux/fs/fifo.c
    3  *
    4  *  written by Paul H. Hargrove
    5  *
    6  *  Fixes:
    7  *      10-06-1999, AV: fixed OOM handling in fifo_open(), moved
    8  *                      initialization there, switched to external
    9  *                      allocation of pipe_inode_info.
   10  */
   11 
   12 #include <linux/mm.h>
   13 #include <linux/fs.h>
   14 #include <linux/sched.h>
   15 #include <linux/pipe_fs_i.h>
   16 
   17 static int wait_for_partner(struct inode* inode, unsigned int *cnt)
   18 {
   19         int cur = *cnt; 
   20 
   21         while (cur == *cnt) {
   22                 pipe_wait(inode->i_pipe);
   23                 if (signal_pending(current))
   24                         break;
   25         }
   26         return cur == *cnt ? -ERESTARTSYS : 0;
   27 }
   28 
   29 static void wake_up_partner(struct inode* inode)
   30 {
   31         wake_up_interruptible(&inode->i_pipe->wait);
   32 }
   33 
   34 static int fifo_open(struct inode *inode, struct file *filp)
   35 {
   36         struct pipe_inode_info *pipe;
   37         int ret;
   38 
   39         mutex_lock(&inode->i_mutex);
   40         pipe = inode->i_pipe;
   41         if (!pipe) {
   42                 ret = -ENOMEM;
   43                 pipe = alloc_pipe_info(inode);
   44                 if (!pipe)
   45                         goto err_nocleanup;
   46                 inode->i_pipe = pipe;
   47         }
   48         filp->f_version = 0;
   49 
   50         /* We can only do regular read/write on fifos */
   51         filp->f_mode &= (FMODE_READ | FMODE_WRITE);
   52 
   53         switch (filp->f_mode) {
   54         case FMODE_READ:
   55         /*
   56          *  O_RDONLY
   57          *  POSIX.1 says that O_NONBLOCK means return with the FIFO
   58          *  opened, even when there is no process writing the FIFO.
   59          */
   60                 filp->f_op = &read_pipefifo_fops;
   61                 pipe->r_counter++;
   62                 if (pipe->readers++ == 0)
   63                         wake_up_partner(inode);
   64 
   65                 if (!pipe->writers) {
   66                         if ((filp->f_flags & O_NONBLOCK)) {
   67                                 /* suppress POLLHUP until we have
   68                                  * seen a writer */
   69                                 filp->f_version = pipe->w_counter;
   70                         } else {
   71                                 if (wait_for_partner(inode, &pipe->w_counter))
   72                                         goto err_rd;
   73                         }
   74                 }
   75                 break;
   76         
   77         case FMODE_WRITE:
   78         /*
   79          *  O_WRONLY
   80          *  POSIX.1 says that O_NONBLOCK means return -1 with
   81          *  errno=ENXIO when there is no process reading the FIFO.
   82          */
   83                 ret = -ENXIO;
   84                 if ((filp->f_flags & O_NONBLOCK) && !pipe->readers)
   85                         goto err;
   86 
   87                 filp->f_op = &write_pipefifo_fops;
   88                 pipe->w_counter++;
   89                 if (!pipe->writers++)
   90                         wake_up_partner(inode);
   91 
   92                 if (!pipe->readers) {
   93                         if (wait_for_partner(inode, &pipe->r_counter))
   94                                 goto err_wr;
   95                 }
   96                 break;
   97         
   98         case FMODE_READ | FMODE_WRITE:
   99         /*
  100          *  O_RDWR
  101          *  POSIX.1 leaves this case "undefined" when O_NONBLOCK is set.
  102          *  This implementation will NEVER block on a O_RDWR open, since
  103          *  the process can at least talk to itself.
  104          */
  105                 filp->f_op = &rdwr_pipefifo_fops;
  106 
  107                 pipe->readers++;
  108                 pipe->writers++;
  109                 pipe->r_counter++;
  110                 pipe->w_counter++;
  111                 if (pipe->readers == 1 || pipe->writers == 1)
  112                         wake_up_partner(inode);
  113                 break;
  114 
  115         default:
  116                 ret = -EINVAL;
  117                 goto err;
  118         }
  119 
  120         /* Ok! */
  121         mutex_unlock(&inode->i_mutex);
  122         return 0;
  123 
  124 err_rd:
  125         if (!--pipe->readers)
  126                 wake_up_interruptible(&pipe->wait);
  127         ret = -ERESTARTSYS;
  128         goto err;
  129 
  130 err_wr:
  131         if (!--pipe->writers)
  132                 wake_up_interruptible(&pipe->wait);
  133         ret = -ERESTARTSYS;
  134         goto err;
  135 
  136 err:
  137         if (!pipe->readers && !pipe->writers)
  138                 free_pipe_info(inode);
  139 
  140 err_nocleanup:
  141         mutex_unlock(&inode->i_mutex);
  142         return ret;
  143 }
  144 
  145 /*
  146  * Dummy default file-operations: the only thing this does
  147  * is contain the open that then fills in the correct operations
  148  * depending on the access mode of the file...
  149  */
  150 const struct file_operations def_fifo_fops = {
  151         .open           = fifo_open,    /* will set read_ or write_pipefifo_fops */
  152         .llseek         = noop_llseek,
  153 };

Cache object: a2d7168c29c0c5189f0c1728fd21602c


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