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/slab.h>
   14 #include <linux/smp_lock.h>
   15 
   16 static void wait_for_partner(struct inode* inode, unsigned int* cnt)
   17 {
   18         int cur = *cnt; 
   19         while(cur == *cnt) {
   20                 pipe_wait(inode);
   21                 if(signal_pending(current))
   22                         break;
   23         }
   24 }
   25 
   26 static void wake_up_partner(struct inode* inode)
   27 {
   28         wake_up_interruptible(PIPE_WAIT(*inode));
   29 }
   30 
   31 static int fifo_open(struct inode *inode, struct file *filp)
   32 {
   33         int ret;
   34 
   35         ret = -ERESTARTSYS;
   36         lock_kernel();
   37         if (down_interruptible(PIPE_SEM(*inode)))
   38                 goto err_nolock_nocleanup;
   39 
   40         if (!inode->i_pipe) {
   41                 ret = -ENOMEM;
   42                 if(!pipe_new(inode))
   43                         goto err_nocleanup;
   44         }
   45         filp->f_version = 0;
   46 
   47         switch (filp->f_mode) {
   48         case 1:
   49         /*
   50          *  O_RDONLY
   51          *  POSIX.1 says that O_NONBLOCK means return with the FIFO
   52          *  opened, even when there is no process writing the FIFO.
   53          */
   54                 filp->f_op = &read_fifo_fops;
   55                 PIPE_RCOUNTER(*inode)++;
   56                 if (PIPE_READERS(*inode)++ == 0)
   57                         wake_up_partner(inode);
   58 
   59                 if (!PIPE_WRITERS(*inode)) {
   60                         if ((filp->f_flags & O_NONBLOCK)) {
   61                                 /* suppress POLLHUP until we have
   62                                  * seen a writer */
   63                                 filp->f_version = PIPE_WCOUNTER(*inode);
   64                         } else 
   65                         {
   66                                 wait_for_partner(inode, &PIPE_WCOUNTER(*inode));
   67                                 if(signal_pending(current))
   68                                         goto err_rd;
   69                         }
   70                 }
   71                 break;
   72         
   73         case 2:
   74         /*
   75          *  O_WRONLY
   76          *  POSIX.1 says that O_NONBLOCK means return -1 with
   77          *  errno=ENXIO when there is no process reading the FIFO.
   78          */
   79                 ret = -ENXIO;
   80                 if ((filp->f_flags & O_NONBLOCK) && !PIPE_READERS(*inode))
   81                         goto err;
   82 
   83                 filp->f_op = &write_fifo_fops;
   84                 PIPE_WCOUNTER(*inode)++;
   85                 if (!PIPE_WRITERS(*inode)++)
   86                         wake_up_partner(inode);
   87 
   88                 if (!PIPE_READERS(*inode)) {
   89                         wait_for_partner(inode, &PIPE_RCOUNTER(*inode));
   90                         if (signal_pending(current))
   91                                 goto err_wr;
   92                 }
   93                 break;
   94         
   95         case 3:
   96         /*
   97          *  O_RDWR
   98          *  POSIX.1 leaves this case "undefined" when O_NONBLOCK is set.
   99          *  This implementation will NEVER block on a O_RDWR open, since
  100          *  the process can at least talk to itself.
  101          */
  102                 filp->f_op = &rdwr_fifo_fops;
  103 
  104                 PIPE_READERS(*inode)++;
  105                 PIPE_WRITERS(*inode)++;
  106                 PIPE_RCOUNTER(*inode)++;
  107                 PIPE_WCOUNTER(*inode)++;
  108                 if (PIPE_READERS(*inode) == 1 || PIPE_WRITERS(*inode) == 1)
  109                         wake_up_partner(inode);
  110                 break;
  111 
  112         default:
  113                 ret = -EINVAL;
  114                 goto err;
  115         }
  116 
  117         /* Ok! */
  118         up(PIPE_SEM(*inode));
  119         unlock_kernel();
  120         return 0;
  121 
  122 err_rd:
  123         if (!--PIPE_READERS(*inode))
  124                 wake_up_interruptible(PIPE_WAIT(*inode));
  125         ret = -ERESTARTSYS;
  126         goto err;
  127 
  128 err_wr:
  129         if (!--PIPE_WRITERS(*inode))
  130                 wake_up_interruptible(PIPE_WAIT(*inode));
  131         ret = -ERESTARTSYS;
  132         goto err;
  133 
  134 err:
  135         if (!PIPE_READERS(*inode) && !PIPE_WRITERS(*inode)) {
  136                 struct pipe_inode_info *info = inode->i_pipe;
  137                 inode->i_pipe = NULL;
  138                 free_page((unsigned long)info->base);
  139                 kfree(info);
  140         }
  141 
  142 err_nocleanup:
  143         up(PIPE_SEM(*inode));
  144 
  145 err_nolock_nocleanup:
  146         unlock_kernel();
  147         return ret;
  148 }
  149 
  150 /*
  151  * Dummy default file-operations: the only thing this does
  152  * is contain the open that then fills in the correct operations
  153  * depending on the access mode of the file...
  154  */
  155 struct file_operations def_fifo_fops = {
  156         open:           fifo_open,      /* will set read or write pipe_fops */
  157 };

Cache object: 8b8d7a159192f8119ecf56d90e73cdf9


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