root/fs/pipe.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pipe_read
  2. pipe_write
  3. pipe_lseek
  4. pipe_readdir
  5. bad_pipe_rw
  6. pipe_ioctl
  7. sys_pipe

   1 /*
   2  *  linux/fs/pipe.c
   3  *
   4  *  (C) 1991  Linus Torvalds
   5  */
   6 
   7 #include <signal.h>
   8 #include <errno.h>
   9 #include <termios.h>
  10 #include <fcntl.h>
  11 
  12 #include <asm/segment.h>
  13 
  14 #include <linux/sched.h>
  15 #include <linux/kernel.h>
  16 
  17 static int pipe_read(struct inode * inode, struct file * filp, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  18 {
  19         int chars, size, read = 0;
  20 
  21         if (!(filp->f_flags & O_NONBLOCK))
  22                 while (!PIPE_SIZE(*inode)) {
  23                         wake_up(& PIPE_WRITE_WAIT(*inode));
  24                         if (inode->i_count != 2) /* are there any writers? */
  25                                 return 0;
  26                         if (current->signal & ~current->blocked)
  27                                 return -ERESTARTSYS;
  28                         interruptible_sleep_on(& PIPE_READ_WAIT(*inode));
  29                 }
  30         while (count>0 && (size = PIPE_SIZE(*inode))) {
  31                 chars = PAGE_SIZE-PIPE_TAIL(*inode);
  32                 if (chars > count)
  33                         chars = count;
  34                 if (chars > size)
  35                         chars = size;
  36                 count -= chars;
  37                 read += chars;
  38                 size = PIPE_TAIL(*inode);
  39                 PIPE_TAIL(*inode) += chars;
  40                 PIPE_TAIL(*inode) &= (PAGE_SIZE-1);
  41                 while (chars-->0)
  42                         put_fs_byte(((char *)inode->i_size)[size++],buf++);
  43         }
  44         wake_up(& PIPE_WRITE_WAIT(*inode));
  45         return read?read:-EAGAIN;
  46 }
  47         
  48 static int pipe_write(struct inode * inode, struct file * filp, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  49 {
  50         int chars, size, written = 0;
  51 
  52         while (count>0) {
  53                 while (!(size=(PAGE_SIZE-1)-PIPE_SIZE(*inode))) {
  54                         wake_up(& PIPE_READ_WAIT(*inode));
  55                         if (inode->i_count != 2) { /* no readers */
  56                                 current->signal |= (1<<(SIGPIPE-1));
  57                                 return written?written:-EINTR;
  58                         }
  59                         if (current->signal & ~current->blocked)
  60                                 return written?written:-EINTR;
  61                         interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode));
  62                 }
  63                 chars = PAGE_SIZE-PIPE_HEAD(*inode);
  64                 if (chars > count)
  65                         chars = count;
  66                 if (chars > size)
  67                         chars = size;
  68                 count -= chars;
  69                 written += chars;
  70                 size = PIPE_HEAD(*inode);
  71                 PIPE_HEAD(*inode) += chars;
  72                 PIPE_HEAD(*inode) &= (PAGE_SIZE-1);
  73                 while (chars-->0)
  74                         ((char *)inode->i_size)[size++]=get_fs_byte(buf++);
  75         }
  76         wake_up(& PIPE_READ_WAIT(*inode));
  77         return written;
  78 }
  79 
  80 static int pipe_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
     /* [previous][next][first][last][top][bottom][index][help] */
  81 {
  82         return -ESPIPE;
  83 }
  84 
  85 static int pipe_readdir(struct inode * inode, struct file * file, struct dirent * de, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  86 {
  87         return -ENOTDIR;
  88 }
  89 
  90 static int bad_pipe_rw(struct inode * inode, struct file * filp, char * buf, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
  91 {
  92         return -EBADF;
  93 }
  94 
  95 static int pipe_ioctl(struct inode *pino, struct file * filp,
     /* [previous][next][first][last][top][bottom][index][help] */
  96         unsigned int cmd, unsigned int arg)
  97 {
  98         switch (cmd) {
  99                 case FIONREAD:
 100                         verify_area((void *) arg,4);
 101                         put_fs_long(PIPE_SIZE(*pino),(unsigned long *) arg);
 102                         return 0;
 103                 default:
 104                         return -EINVAL;
 105         }
 106 }
 107 
 108 static struct file_operations read_pipe_fops = {
 109         pipe_lseek,
 110         pipe_read,
 111         bad_pipe_rw,
 112         pipe_readdir,
 113         NULL,           /* pipe_close */
 114         NULL,           /* pipe_select */
 115         pipe_ioctl
 116 };
 117 
 118 static struct file_operations write_pipe_fops = {
 119         pipe_lseek,
 120         bad_pipe_rw,
 121         pipe_write,
 122         pipe_readdir,
 123         NULL,           /* pipe_close */
 124         NULL,           /* pipe_select */
 125         pipe_ioctl
 126 };
 127 
 128 int sys_pipe(unsigned long * fildes)
     /* [previous][next][first][last][top][bottom][index][help] */
 129 {
 130         struct inode * inode;
 131         struct file * f[2];
 132         int fd[2];
 133         int i,j;
 134 
 135         j=0;
 136         for(i=0;j<2 && i<NR_FILE;i++)
 137                 if (!file_table[i].f_count)
 138                         (f[j++]=i+file_table)->f_count++;
 139         if (j==1)
 140                 f[0]->f_count=0;
 141         if (j<2)
 142                 return -1;
 143         j=0;
 144         for(i=0;j<2 && i<NR_OPEN;i++)
 145                 if (!current->filp[i]) {
 146                         current->filp[ fd[j]=i ] = f[j];
 147                         j++;
 148                 }
 149         if (j==1)
 150                 current->filp[fd[0]]=NULL;
 151         if (j<2) {
 152                 f[0]->f_count=f[1]->f_count=0;
 153                 return -1;
 154         }
 155         if (!(inode=get_pipe_inode())) {
 156                 current->filp[fd[0]] =
 157                         current->filp[fd[1]] = NULL;
 158                 f[0]->f_count = f[1]->f_count = 0;
 159                 return -1;
 160         }
 161         f[0]->f_inode = f[1]->f_inode = inode;
 162         f[0]->f_pos = f[1]->f_pos = 0;
 163         f[0]->f_op = &read_pipe_fops;
 164         f[0]->f_mode = 1;               /* read */
 165         f[1]->f_op = &write_pipe_fops;
 166         f[1]->f_mode = 2;               /* write */
 167         put_fs_long(fd[0],0+fildes);
 168         put_fs_long(fd[1],1+fildes);
 169         return 0;
 170 }

/* [previous][next][first][last][top][bottom][index][help] */