linux-old/fs/fifo.c
<<
>>
Prefs
   1/*
   2 *  linux/fs/fifo.c
   3 *
   4 *  written by Paul H. Hargrove
   5 */
   6
   7#include <linux/mm.h>
   8
   9static int fifo_open(struct inode * inode,struct file * filp)
  10{
  11        int retval = 0;
  12        unsigned long page;
  13
  14        switch( filp->f_mode ) {
  15
  16        case 1:
  17        /*
  18         *  O_RDONLY
  19         *  POSIX.1 says that O_NONBLOCK means return with the FIFO
  20         *  opened, even when there is no process writing the FIFO.
  21         */
  22                filp->f_op = &connecting_fifo_fops;
  23                if (!PIPE_READERS(*inode)++)
  24                        wake_up_interruptible(&PIPE_WAIT(*inode));
  25                if (!(filp->f_flags & O_NONBLOCK) && !PIPE_WRITERS(*inode)) {
  26                        PIPE_RD_OPENERS(*inode)++;
  27                        while (!PIPE_WRITERS(*inode)) {
  28                                if (signal_pending(current)) {
  29                                        retval = -ERESTARTSYS;
  30                                        break;
  31                                }
  32                                interruptible_sleep_on(&PIPE_WAIT(*inode));
  33                        }
  34                        if (!--PIPE_RD_OPENERS(*inode))
  35                                wake_up_interruptible(&PIPE_WAIT(*inode));
  36                }
  37                while (PIPE_WR_OPENERS(*inode))
  38                        interruptible_sleep_on(&PIPE_WAIT(*inode));
  39                if (PIPE_WRITERS(*inode))
  40                        filp->f_op = &read_fifo_fops;
  41                if (retval && !--PIPE_READERS(*inode))
  42                        wake_up_interruptible(&PIPE_WAIT(*inode));
  43                break;
  44        
  45        case 2:
  46        /*
  47         *  O_WRONLY
  48         *  POSIX.1 says that O_NONBLOCK means return -1 with
  49         *  errno=ENXIO when there is no process reading the FIFO.
  50         */
  51                if ((filp->f_flags & O_NONBLOCK) && !PIPE_READERS(*inode)) {
  52                        retval = -ENXIO;
  53                        break;
  54                }
  55                filp->f_op = &write_fifo_fops;
  56                if (!PIPE_WRITERS(*inode)++)
  57                        wake_up_interruptible(&PIPE_WAIT(*inode));
  58                if (!PIPE_READERS(*inode)) {
  59                        PIPE_WR_OPENERS(*inode)++;
  60                        while (!PIPE_READERS(*inode)) {
  61                                if (signal_pending(current)) {
  62                                        retval = -ERESTARTSYS;
  63                                        break;
  64                                }
  65                                interruptible_sleep_on(&PIPE_WAIT(*inode));
  66                        }
  67                        if (!--PIPE_WR_OPENERS(*inode))
  68                                wake_up_interruptible(&PIPE_WAIT(*inode));
  69                }
  70                while (PIPE_RD_OPENERS(*inode))
  71                        interruptible_sleep_on(&PIPE_WAIT(*inode));
  72                if (retval && !--PIPE_WRITERS(*inode))
  73                        wake_up_interruptible(&PIPE_WAIT(*inode));
  74                break;
  75        
  76        case 3:
  77        /*
  78         *  O_RDWR
  79         *  POSIX.1 leaves this case "undefined" when O_NONBLOCK is set.
  80         *  This implementation will NEVER block on a O_RDWR open, since
  81         *  the process can at least talk to itself.
  82         */
  83                filp->f_op = &rdwr_fifo_fops;
  84                if (!PIPE_READERS(*inode)++)
  85                        wake_up_interruptible(&PIPE_WAIT(*inode));
  86                while (PIPE_WR_OPENERS(*inode))
  87                        interruptible_sleep_on(&PIPE_WAIT(*inode));
  88                if (!PIPE_WRITERS(*inode)++)
  89                        wake_up_interruptible(&PIPE_WAIT(*inode));
  90                while (PIPE_RD_OPENERS(*inode))
  91                        interruptible_sleep_on(&PIPE_WAIT(*inode));
  92                break;
  93
  94        default:
  95                retval = -EINVAL;
  96        }
  97        if (retval || PIPE_BASE(*inode))
  98                return retval;
  99        page = __get_free_page(GFP_KERNEL);
 100        if (PIPE_BASE(*inode)) {
 101                free_page(page);
 102                return 0;
 103        }
 104        if (!page)
 105                return -ENOMEM;
 106        PIPE_LOCK(*inode) = 0;
 107        PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
 108        PIPE_BASE(*inode) = (char *) page;
 109        return 0;
 110}
 111
 112/*
 113 * Dummy default file-operations: the only thing this does
 114 * is contain the open that then fills in the correct operations
 115 * depending on the access mode of the file...
 116 */
 117static struct file_operations def_fifo_fops = {
 118        NULL,
 119        NULL,
 120        NULL,
 121        NULL,
 122        NULL,
 123        NULL,
 124        NULL,
 125        fifo_open,              /* will set read or write pipe_fops */
 126        NULL,
 127        NULL,
 128        NULL,
 129        NULL
 130};
 131
 132struct inode_operations fifo_inode_operations = {
 133        &def_fifo_fops,         /* default file operations */
 134        NULL,                   /* create */
 135        NULL,                   /* lookup */
 136        NULL,                   /* link */
 137        NULL,                   /* unlink */
 138        NULL,                   /* symlink */
 139        NULL,                   /* mkdir */
 140        NULL,                   /* rmdir */
 141        NULL,                   /* mknod */
 142        NULL,                   /* rename */
 143        NULL,                   /* readlink */
 144        NULL,                   /* readpage */
 145        NULL,                   /* writepage */
 146        NULL,                   /* bmap */
 147        NULL,                   /* truncate */
 148        NULL                    /* permission */
 149};
 150
 151void init_fifo(struct inode * inode)
 152{
 153        inode->i_op = &fifo_inode_operations;
 154        PIPE_LOCK(*inode) = 0;
 155        PIPE_BASE(*inode) = NULL;
 156        PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
 157        PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0;
 158        PIPE_WAIT(*inode) = NULL;
 159        PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
 160}
 161
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.