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