home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.2 / LINUX-1.2 / LINUX-1 / linux / fs / fifo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-23  |  3.9 KB  |  163 lines

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