Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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/fs.h>
 15 #include <linux/sched.h>
 16 #include <linux/pipe_fs_i.h>
 17 
 18 static void wait_for_partner(struct inode* inode, unsigned int *cnt)
 19 {
 20         int cur = *cnt; 
 21 
 22         while (cur == *cnt) {
 23                 pipe_wait(inode->i_pipe);
 24                 if (signal_pending(current))
 25                         break;
 26         }
 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                         {
 72                                 wait_for_partner(inode, &pipe->w_counter);
 73                                 if(signal_pending(current))
 74                                         goto err_rd;
 75                         }
 76                 }
 77                 break;
 78         
 79         case FMODE_WRITE:
 80         /*
 81          *  O_WRONLY
 82          *  POSIX.1 says that O_NONBLOCK means return -1 with
 83          *  errno=ENXIO when there is no process reading the FIFO.
 84          */
 85                 ret = -ENXIO;
 86                 if ((filp->f_flags & O_NONBLOCK) && !pipe->readers)
 87                         goto err;
 88 
 89                 filp->f_op = &write_pipefifo_fops;
 90                 pipe->w_counter++;
 91                 if (!pipe->writers++)
 92                         wake_up_partner(inode);
 93 
 94                 if (!pipe->readers) {
 95                         wait_for_partner(inode, &pipe->r_counter);
 96                         if (signal_pending(current))
 97                                 goto err_wr;
 98                 }
 99                 break;
100         
101         case FMODE_READ | FMODE_WRITE:
102         /*
103          *  O_RDWR
104          *  POSIX.1 leaves this case "undefined" when O_NONBLOCK is set.
105          *  This implementation will NEVER block on a O_RDWR open, since
106          *  the process can at least talk to itself.
107          */
108                 filp->f_op = &rdwr_pipefifo_fops;
109 
110                 pipe->readers++;
111                 pipe->writers++;
112                 pipe->r_counter++;
113                 pipe->w_counter++;
114                 if (pipe->readers == 1 || pipe->writers == 1)
115                         wake_up_partner(inode);
116                 break;
117 
118         default:
119                 ret = -EINVAL;
120                 goto err;
121         }
122 
123         /* Ok! */
124         mutex_unlock(&inode->i_mutex);
125         return 0;
126 
127 err_rd:
128         if (!--pipe->readers)
129                 wake_up_interruptible(&pipe->wait);
130         ret = -ERESTARTSYS;
131         goto err;
132 
133 err_wr:
134         if (!--pipe->writers)
135                 wake_up_interruptible(&pipe->wait);
136         ret = -ERESTARTSYS;
137         goto err;
138 
139 err:
140         if (!pipe->readers && !pipe->writers)
141                 free_pipe_info(inode);
142 
143 err_nocleanup:
144         mutex_unlock(&inode->i_mutex);
145         return ret;
146 }
147 
148 /*
149  * Dummy default file-operations: the only thing this does
150  * is contain the open that then fills in the correct operations
151  * depending on the access mode of the file...
152  */
153 const struct file_operations def_fifo_fops = {
154         .open           = fifo_open,    /* will set read_ or write_pipefifo_fops */
155 };
156 
  This page was automatically generated by the LXR engine.